जिस तरह से यह करता है, उसके लिए C ++ मानक हैंडल फ़ाइल क्यों करता है?


17

C ++ streamoffएक (फ़ाइल) स्ट्रीम के भीतर एक ऑफसेट का प्रतिनिधित्व करने के लिए प्रकार का उपयोग करता है और इसे इस तरह परिभाषित किया जाता है: [stream.types]:

using streamoff = implementation-defined ;

टाइप स्ट्रीमऑफ़ ऑपरेटिंग सिस्टम के लिए अधिकतम संभव फ़ाइल आकार का प्रतिनिधित्व करने के लिए पर्याप्त आकार के हस्ताक्षरित मूल अभिन्न प्रकारों में से एक का एक पर्याय है। 287)

287) आमतौर पर लंबे समय तक।

यह समझ में आता है क्योंकि यह बड़ी फ़ाइलों के भीतर (जैसा कि उपयोग करने के लिए विरोध longकिया जा सकता है, जो केवल 32 बिट्स चौड़ा हो सकता है) के लिए अनुमति देता है।

[filebuf.virtuals] basic_filebufफ़ाइल के भीतर खोज करने के लिए फ़ंक्शन को निम्नानुसार परिभाषित करता है:

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;

off_typeके बराबर है streamoff, देखें [iostreams.limits.pos]। हालांकि, मानक तब फ़ंक्शन के प्रभावों की व्याख्या करता है। मुझे बहुत अंतिम वाक्य से चिढ़ है, जिसके लिए कॉल की आवश्यकता है fseek:

प्रभाव : widthनिरूपित करते हैं a_codecvt.encoding()। यदि is_open() == false, या off != 0 && width <= 0, तो स्थिति संचालन विफल हो जाता है। अन्यथा, यदि way != basic_ios::curया off != 0, और यदि अंतिम ऑपरेशन आउटपुट था, तो आउटपुट अनुक्रम को अपडेट करें और कोई भी अनशिफ्ट अनुक्रम लिखें। अगला, नई स्थिति की तलाश करें: यदि width > 0, कॉल करें fseek(file, width * off, whence), अन्यथा कॉल करें fseek(file, 0, whence)

fseekएक longपैरामीटर स्वीकार करता है । यदि off_typeऔर (मानक के अनुसार सुझाव दिया गया है) के streamoffरूप में परिभाषित long longकिया गया है, तो यह longकॉल करते समय रूपांतरण को कम कर सकता है fseek(file, width * off, whence)(कीड़े का निदान करने के लिए संभावित रूप से कठिन हो सकता है)। यह streamoffपहली जगह में प्रकार को शुरू करने के लिए पूरे तर्क को प्रश्न में रखता है।

क्या यह जानबूझकर या मानक में एक दोष है?


8
दोष जैसा दिखता है।
यक्क - एडम नेवरामॉन्ट

मुझे लगता है कि मुझे लगता है कि gcc libstdc ++ fseeko64 का उपयोग करता है ।
कामिलुक

1
ऑफहैंड, यह हुड के नीचे seekoffजरूरी उपयोग की तरह नहीं दिखता है fseek। बल्कि, (संभवतः परिचित?) व्यवहार का fseekउपयोग यह बताने के लिए किया जाता है कि क्या seekoffकर रहा है।
jjramsey

@jjramsey यह मेरी धारणा थी। हालाँकि, जिस तरह से इसे अभिव्यक्त किया गया है वह स्पष्टीकरण के बजाय एक आवश्यकता का सुझाव देता है।
२०

1
@jjramsey मैं सहमत हूं कि "प्रभाव" भाग को यथोचित रूप से व्याख्या करने के लिए समझा जा सकता है कि इसे वास्तव में तब तक कॉल करने की आवश्यकता नहीं है fseekजब तक यह समान प्रभाव के साथ कुछ करता है। लेकिन fseekकम LONG_MINया अधिक से अधिक ऑफसेट के साथ LONG_MAXकोई प्रभाव नहीं होता है, इसलिए स्पष्टीकरण सबसे अधूरा है, कम से कम कार्यान्वयन के लिए जहां streamoffकी तुलना में व्यापक है long
कीथ थॉम्पसन

जवाबों:


6

मुझे लगता है कि जो निष्कर्ष आप इस से खींच रहे हैं, वह यह है कि सी ++ धाराओं के बीच एक बेमेल है और fseekइससे रनटाइम बग पैदा होंगे, गलत है। स्थिति यह प्रतीत होती है:

  1. सिस्टम पर जहां long64 बिट्स है, streamoffको परिभाषित किया गया है long, और seekoffफ़ंक्शन इनवोक करता है fseek

  2. सिस्टम पर जहां long32 बिट लेकिन ओएस का समर्थन करता है 64-बिट फ़ाइल ऑफसेट, है streamoffके रूप में परिभाषित किया गया है long longऔर seekoffएक समारोह या तो कहा जाता है का आह्वान fseekoया fseeko64कि स्वीकार करता है एक 64-बिट ऑफसेट।

यहाँ seekoffमेरे लिनक्स सिस्टम की परिभाषा से स्निपेट है:

#ifdef _GLIBCXX_USE_LFS
    if (!fseeko64(_M_file, __off, __whence))
      __ret = std::streampos(ftello64(_M_file));
#else
    if (!fseek(_M_file, __off, __whence))
      __ret = std::streampos(std::ftell(_M_file));
#endif

LFS बड़े फ़ाइल समर्थन के लिए खड़ा है ।

निष्कर्ष: जबकि मानक इस streamoffबात के लिए एक परिभाषा सुझाता है कि जो अनिवार्य रूप से seekoffआह्वान करने की आवश्यकता के साथ टकराव करता है fseek, पुस्तकालय डिजाइनर समझते हैं कि उन्हें उस संस्करण के कॉल को fseekस्वीकार करना चाहिए जो ओएस का समर्थन करता है।


@ypnos मैंने नीचा नहीं देखा और मुझे यह उत्तर उपयोगी लगा। मुझे लगता है कि किसी ने अपमानित किया क्योंकि यह बात याद आती है। समस्या यह नहीं है कि ऐसे कार्यान्वयन हैं जो इस संबंध में मानक की अनदेखी करते हैं, समस्या यह है कि कार्यान्वयन के लिए मानक को नजरअंदाज करने की आवश्यकता है।
ज्येष्ठ २

6
The situation seems to be:- स्थिति है कि कार्यान्वयन कॉल करने के लिए नहीं की अनुमति नहीं है fseekमें seekoff। यह कॉल करना चाहिए fseek, यह नहीं है, मानक कहते हैं कि यह करने के लिए है। मैं तर्क दे सकता हूं कि यह कार्यान्वयन अमान्य है। मेरा मानना ​​है कि यह सवाल का जवाब नहीं देता है। Och, llvm पाया , यह कहता है fseeko
कामिलकुक

FYI के रूप में, VC + _fseeki64इस फ़ंक्शन के लिए कॉल करता है; जो भी मानक कहता है उसका उल्लंघन करता है।
क्रिसमम

1
यह कार्यान्वयनकर्ताओं को समस्या का एहसास करने और मानक की अनदेखी करने का मामला है। मुझे खुशी है कि उन्होंने किया, लेकिन मानक को ठीक करने की जरूरत है।
नाथनऑलिवर

1
कुछ लोग मानक भी शाब्दिक रूप से ले रहे हैं। यह मांग नहीं है कि कार्यान्वयन शाब्दिक रूप से एक फ़ंक्शन कहलाता है fseek। कहीं और मानक किसी चीज़ का वर्णन करता है "जैसे कि कॉल करके fseek(...)।" यदि यह शाब्दिक रूप से कॉल करने के बारे में इतना ध्यान रखता है, तो यह fseekकथन अलग होगा। गंभीरता से, यदि आप C ++ लाइब्रेरी को लागू कर रहे हैं, तो आप क्या करेंगे? क्या आप fseek64-बिट फ़ाइल ऑफ़सेट के निचले 32 बिट्स के साथ कॉल करने पर ज़ोर देंगे , क्योंकि एक दस्तावेज़ आपको बताता है? क्या आपके ग्राहक इसके लिए आपको धन्यवाद देंगे?
विलिस ब्लैकबर्न
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.