स्वयं के इनिशियलाइज़र में वैरिएबल का उपयोग


22

[basic.scope.pdecl] / C ++ 20 मानक मसौदे में से 1 में नोट में निम्नलिखित (गैर-मानक) उदाहरण था ( पुल अनुरोध के विलय से पहले आंशिक उद्धरण 3580 , इस प्रश्न का उत्तर देखें):

unsigned char x = x;

[...] x को अपने स्वयं के (अनिश्चित) मूल्य के साथ आरंभीकृत किया जाता है।

क्या यह वास्तव में C ++ 20 में अच्छी तरह से परिभाषित व्यवहार है?


आमतौर पर फॉर्म के आत्म-आरंभण T x = x;को अपरिभाषित व्यवहार किया जाता है, xक्योंकि आरंभ होने से पहले मूल्य का अनिश्चित होना अनिश्चित होता है। अनिश्चित मानों का मूल्यांकन आम तौर पर अपरिभाषित व्यवहार ( [बुनियादी .indent / / 2 )) का कारण बनता है , लेकिन [basic.indent] / 2.3 में एक विशिष्ट अपवाद है जो एक चर को सीधे indermerminate मान के साथ आरंभ करने की अनुमति देता है (अनिश्चित मान के साथ आरंभीकरण) )।unsigned charunsigned char

यह अकेले इसलिए अपरिभाषित व्यवहार का कारण नहीं बनता है, लेकिन अन्य प्रकारों के लिए Tजो बिना संकुचित वर्ण प्रकार के या std::byte, उदा int x = x;। C ++ 17 और इससे पहले लागू किए गए ये विचार, नीचे दिए गए लिंक से जुड़े प्रश्न भी देखें।

हालाँकि, unsigned char x = x;वर्तमान ड्राफ्ट के [basic.lifetime] / 7 के लिए भी कहते हैं:

इसी तरह, किसी वस्तु का जीवनकाल शुरू होने से पहले [...] उस गुण के गुणों का उपयोग करना जो उसके मूल्य पर निर्भर नहीं है, अच्छी तरह से परिभाषित है। कार्यक्रम में अपरिभाषित व्यवहार है यदि:

  • glvalue का उपयोग ऑब्जेक्ट तक पहुंचने के लिए किया जाता है, या

  • [...]

इसका अर्थ यह लगता है कि xउदाहरण में इसका मूल्य केवल अपने जीवनकाल के दौरान ही उपयोग किया जा सकता है।

[basic.lifetime] / 1 कहता है:

[...]

एक प्रकार की वस्तु T का जीवनकाल कब शुरू होता है:

  • [...] तथा
  • इसकी इनिशियलाइज़ेशन (यदि कोई है) पूरी हो गई है (रिक्वायर्ड इनिशियलाइज़ेशन सहित) ([dcl.init])

[...]

इस प्रकार xजीवनकाल आरंभ होने के बाद ही शुरू होता है। लेकिन उद्धृत उदाहरण में xमूल्य का उपयोग xपूरा होने से पहले किया जाता है। इसलिए उपयोग में अपरिभाषित व्यवहार है।

क्या मेरा विश्लेषण सही है और अगर ऐसा है, तो क्या यह उपयोग-से-आरंभिककरण जैसे मामलों के समान मामलों को प्रभावित करता है

int x = (x = 1);

जो, जहां तक ​​मैं बता सकता हूं, सी ++ 17 में और साथ ही पहले भी अच्छी तरह से परिभाषित किया गया था?


ध्यान दें कि C ++ 17 (अंतिम ड्राफ्ट) को शुरू करने के लिए जीवनकाल की दूसरी आवश्यकता अलग थी :

  • यदि ऑब्जेक्ट में गैर-रिक्त आरंभीकरण है, तो इसका आरंभीकरण पूर्ण है,

चूँकि xC ++ 17 की परिभाषा (लेकिन वर्तमान ड्राफ्ट में कोई नहीं है) द्वारा प्रारंभिक आरंभीकरण होगा, इसका जीवनकाल पहले ही शुरू हो गया होगा जब इसे ऊपर दिए गए उदाहरणों में इनिशियलाइज़र में एक्सेस किया गया है और इसलिए दोनों उदाहरणों में कोई अपरिभाषित व्यवहार नहीं था xC ++ 17 के जीवनकाल के कारण ।

C ++ 17 से पहले का शब्दांकन फिर से अलग है, लेकिन उसी परिणाम के साथ।


अनिश्चित अनिश्चित मानों का उपयोग करते समय यह सवाल अपरिभाषित व्यवहार के बारे में नहीं है, जो निम्नलिखित प्रश्नों में शामिल किया गया था:


@LanguageLawyer मुझे विश्वास नहीं हो रहा है कि मैं सही हूँ, खासकर नहीं अगर किसी ने अभी तक जवाब नहीं दिया है। यदि अन्य लोग यहां मेरे साथ सहमत होने जा रहे हैं, तो मैं एक बाद में (या शायद कोई और मेरे सामने होगा) फाइल कर सकता है, लेकिन मैं उन मुद्दों को दर्ज नहीं करना चाहता जिनके बारे में मुझे यकीन नहीं है।
अखरोट

@LanguageLawyer: यदि वर्किंग पेपर गलत तरीके से गलत बात कहता है तो यह संपादकीय मुद्दा नहीं हो सकता।
डेविस हेरिंग

1
शब्द P1358 द्वारा बदल दिया गया है ।
xskxzr

1
@xskxzr अधिकार, और इस बीच में LanguageLawyer ने एक संपादकीय मुद्दा भी दायर किया , जो कि आशय के स्पष्टीकरण के लिए CWG को भेज दिया गया है।
अखरोट

1
@ clockw0rk int x ^= x;वाक्यात्मक रूप से अच्छी तरह से गठित नहीं है। आप या तो इनिशियलाइज़र (यानी int x = x;, हालांकि यह यूबी है) या एक एक्सोर असाइनमेंट एक्सप्रेशन स्टेटमेंट के साथ एक वैरिएबल डेफिनिशन हो सकता है (यानी , x ^= x;अगर यह यूबी का है, तो xयह intडिफॉल्ट-इनिशियलाइज़्ड है और पहले से असाइन नहीं किया गया है)। आप इन दोनों को एक में नहीं मिला सकते।
अखरोट

जवाबों:


8

यह एक संपादकीय मुद्दे के रूप में खोला गया था । यह (आंतरिक) चर्चा के लिए सीडब्ल्यूजी को भेजा गया था। लगभग 24 घंटे बाद, इस मुद्दे को आगे बढ़ाने वाले व्यक्ति ने एक पुल अनुरोध बनाया, जो उदाहरण को स्पष्ट करता है कि यह स्पष्ट है कि यह UB है:

यहाँ, दूसरे \ tcode {x} के आरंभीकरण में अपरिभाषित व्यवहार होता है, क्योंकि initializer अपने जीवनकाल के \ _iref {basic.life} के बाहर दूसरे \ tcode {x} को एक्सेस करता है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.