C++ 11 ने std:: string:: data() एक शून्य समाप्ति वर्ण क्यों जोड़ा?




c++11 stdstring (2)

परिवर्तन के लाभ:

  1. जब data भी शून्य टर्मिनेटर की गारंटी देता है, तो प्रोग्रामर को c_str और data बीच अंतर के अस्पष्ट विवरणों को जानने की आवश्यकता नहीं होती है और फलस्वरूप अशक्त व्यवहार से अशक्त व्यवहार से बचने के लिए उन कार्यों में शून्य समाप्ति की गारंटी से बचना चाहिए जिन्हें अशक्तता की आवश्यकता होती है। ऐसे कार्य सी इंटरफेस में सर्वव्यापी हैं, और सी इंटरफेस का उपयोग सी ++ में बहुत किया जाता है।

  2. सबस्क्रिप्ट ऑपरेटर को str[str.size()] तक पढ़ने की अनुमति देने के लिए भी बदल दिया गया था। str.data() + str.size() असंगत होने की अनुमति नहीं दी जाएगी।

  3. जबकि आकार आदि पर शून्य टर्मिनेटर को इनिशियलाइज़ न करना उस ऑपरेशन को तेज़ कर सकता है, यह c_str में आरंभीकरण को बल देता है जो उस फ़ंक्शन को धीमा बनाता है। ऑप्टिमाइज़ेशन केस जो हटा दिया गया था, वह सार्वभौमिक रूप से बेहतर विकल्प नहीं था। बिंदु 2 में उल्लिखित परिवर्तन को देखते हुए। धीमेपन ने सबस्क्रिप्ट ऑपरेटर को भी प्रभावित किया होगा, जो निश्चित रूप से प्रदर्शन के लिए स्वीकार्य नहीं होगा। जैसे, अशक्त टर्मिनेटर वैसे भी होने जा रहा था, और इसलिए यह गारंटी देने में नकारात्मक पक्ष नहीं होगा कि यह है।

जिज्ञासु विस्तार: str.at(str.size()) अभी भी एक अपवाद फेंकता है।

PS एक और बदलाव था, वह यह है कि यह सुनिश्चित करने के लिए कि तार में सन्निहित भंडारण है (यही वजह है कि data पहले स्थान पर प्रदान किया गया है)। C ++ 11 से पहले, कार्यान्वयन में रस्सियों के तार का उपयोग किया जा सकता था, और c_str पर कॉल को पुनः प्राप्त किया जा सकता था। किसी भी बड़े कार्यान्वयन ने इस स्वतंत्रता (मेरे ज्ञान के लिए) का फायदा उठाने के लिए नहीं चुना था।

उदाहरण के लिए GCC के libstdc ++ के पुराने संस्करण ने जाहिरा तौर पर null टर्मिनेटर को केवल c_str संस्करण 3.4 तक सेट किया था। विवरण के लिए संबंधित प्रतिबद्ध देखें।

To इसका एक कारक संगणना है जिसे C ++ 11 में भाषा मानक के लिए पेश किया गया था। समवर्ती गैर-परमाणु संशोधन डेटा-रेस अपरिभाषित व्यवहार है, यही वजह है कि सी ++ संकलक को आक्रामक रूप से अनुकूलन करने और चीजों को रजिस्टर में रखने की अनुमति है। इसलिए साधारण C ++ में लिखी गई लाइब्रेरी कार्यान्वयन में .c_str() समवर्ती कॉल के लिए UB होगा।

व्यवहार में (टिप्पणियों को देखें) एक ही चीज़ को लिखने वाले कई सूत्र होने के कारण शुद्धता की समस्या नहीं होगी क्योंकि वास्तविक सीपीयू के लिए asm में UB नहीं है। और C ++ UB नियमों का मतलब है कि कई सूत्र वास्तव में एक std::string object ( c_str() कॉलिंग के अलावा) को बिना सिंक्रोनाइज़ेशन के संशोधित कर रहे हैं, ऐसा कुछ है जो कंपाइलर + लाइब्रेरी मान सकता है कि ऐसा नहीं होता है।

लेकिन यह कैश को गंदा कर देगा और अन्य थ्रेड्स को पढ़ने से रोक देगा, इसलिए अभी भी एक खराब विकल्प है, विशेष रूप से स्ट्रिंग्स के लिए जो संभवतः समवर्ती पाठक हैं। इसके अलावा यह .c_str() मूल रूप से स्टोर साइड-इफ़ेक्ट की वजह से दूर होने से अनुकूलन करना बंद कर .c_str()

पहले जो std::string::c_str() की नौकरी थी, लेकिन C ++ 11 के अनुसार, data() भी यह प्रदान करता है, क्यों c_str() का null-terminating-character को std::string::data() जोड़ा गया std::string::data() ? मेरे लिए यह सीपीयू चक्रों की बर्बादी की तरह लगता है, ऐसे मामलों में जहां शून्य-समाप्ति-चरित्र बिल्कुल भी प्रासंगिक नहीं है और केवल data() का उपयोग किया जाता है, एक C ++ 03 संकलक को टर्मिनेटर के बारे में परवाह नहीं है, और हर बार स्ट्रिंग के आकार बदलने पर टर्मिनेटर को 0 नहीं लिखना पड़ता है, लेकिन data() की वजह से C ++ 11 कंपाइलर, data() -नुल गारंटी की वजह से, स्ट्रिंग के आकार बदल जाने पर, हर बार 0 लिखना बेकार हो जाता है, इसलिए चूंकि यह संभावित रूप से कोड को धीमा बनाता है, मुझे लगता है कि उनके पास उस गारंटी को जोड़ने का कोई कारण था, यह क्या था?


प्रश्न का आधार समस्याग्रस्त है।

एक स्ट्रिंग क्लास को बहुत विस्तारक चीजें करनी होती हैं, जैसे डायनामिक मेमोरी को आवंटित करना, बाइट्स को एक बफर से दूसरे में कॉपी करना, अंतर्निहित मेमोरी को मुक्त करना इत्यादि।

क्या आप एक घटिया mov विधानसभा निर्देश है? मेरा विश्वास करो, यह आपके प्रदर्शन को 0.5% तक भी प्रभावित नहीं करता है।

प्रोग्रामिंग भाषा रनटाइम लिखते समय, आप हर छोटे विधानसभा निर्देश के बारे में जुनूनी नहीं हो सकते। आपको समझदारी से अपनी अनुकूलन लड़ाइयों को चुनना होगा, और अन-नोटिबल नल समाप्ति को अनुकूलित करना उनमें से एक नहीं है।

इस विशिष्ट मामले में, सी के साथ संगत होना शून्य समाप्ति की तुलना में अधिक महत्वपूर्ण है।





c++03