2015-10-31 10 views
8

यदि स्थैतिक-भंडारण अवधि वाले किसी ऑब्जेक्ट के लिए कोई C++ कन्स्ट्रक्टर किसी सदस्य को प्रारंभ नहीं करता है, तो क्या यह पूर्व शून्य-प्रारंभिकता को संरक्षित करने के लिए आवश्यक है, या क्या यह सदस्य को अनिश्चित मान के साथ छोड़ देता है?क्या सी ++ डिफ़ॉल्ट-प्रारंभिकता पूर्व शून्य-प्रारंभिकता को सुरक्षित रखती है?

सी ++ spec का मेरा पठन यह है कि यह खुद के विपरीत है।

उदाहरण:

#include <iostream> 

struct Foo { Foo(); int x; } object; 

Foo::Foo() { } 

int main() { std::cout << object.x << std::endl; } 

फू() निर्माता स्पष्ट रूप से 12.6.2 पैरा 8 में तो टिप्पणी के अनुसार, सदस्य object.x प्रारंभ नहीं करता है:

सदस्य है अनिश्चित मूल्य।

लेकिन विभिन्न प्रारंभिकरणों के विवरण के माध्यम से काम करते हुए, यह गलत लगता है। सदस्य object.x शून्य-प्रारंभिक है क्योंकि इसमें स्थैतिक-भंडारण-अवधि है, और फिर मैं कुछ भी नहीं देख सकता जो इसे बदलता है।

निर्माता के बारे में, 12.6.2 में पाठ लागू होने वाला है:

इकाई डिफ़ॉल्ट-प्रारंभ है।

8,5 पैरा 7 में, डिफ़ॉल्ट आरंभीकरण के संबंधित मामला है:

... कोई प्रारंभ

जो मेरा मतलब है कि पिछले शून्य आरंभीकरण है पढ़ा किया जाता है डिफ़ॉल्ट-प्रारंभिकरण द्वारा नहीं बदला गया।

क्या मुझे कुछ अन्य पाठ याद आ रहा है जो सभी सदस्यों को कन्स्ट्रक्टर कॉल की शुरुआत में "अनिश्चित मूल्य" में रीसेट करता है?

मैं शून्य आरंभीकरण और डिफ़ॉल्ट-आरंभीकरण के बारे में stackoverflow पर विभिन्न अन्य प्रश्न पाया, लेकिन मैं नहीं देख सकता था विश्लेषण किया किसी भी है कि क्या जब डिफ़ॉल्ट-आरंभीकरण एक ही इकाई के कुछ जल्दी प्रारंभ इस प्रकार होता है।

इस मामले में शायद कोई व्यावहारिक प्रभाव नहीं है। लेकिन एक और जटिल कन्स्ट्रक्टर में, कुछ सदस्यों के साथ शुरू हुआ और अन्य नहीं, क्या संकलक को ट्रैक करना है कि बाइट्स/बिट्स को किस प्रकार शुरू किया गया है ?, या यह सिर्फ पूरे ऑब्जेक्ट को प्रारंभ कर सकता है (उदाहरण के लिए, मेमसेट() कॉलर को कन्स्ट्रक्टर को सरल बनाना)?

+2

मैंने अपना जवाब हटा दिया क्योंकि एक मोड़ है जिसके बारे में मुझे यकीन नहीं है: 'फू' गैर-तुच्छ प्रारंभिकता वाला एक ऑब्जेक्ट है, जिसका अर्थ यह है कि इसका कन्स्ट्रक्टर पूरा होने के बाद ही इसका जीवनकाल शुरू हो गया है। मैं इसके सदस्यों के मूल्यों के बारे में निश्चित नहीं हूं। कन्स्ट्रक्टर ने निष्पादन शुरू करने से पहले, आप उन्हें (मानक नियमों के अनुसार) तक भी नहीं पहुंच सकते हैं, इसलिए मेरे पास मुश्किल समय है कि उनके पास उस समय तक मूल्य मान (शून्य) संग्रहीत है .. पहले किसी ऑब्जेक्ट के अस्तित्व का उल्लेख न करें जगह। –

+0

@ लाइटनेसरेसेसिन ऑर्बिट फिर "एह नहीं, अगर यह केवल मसौदे में है तो यह मानक में नहीं है और इस पर भरोसा नहीं किया जाना चाहिए" .. तो हमें लगता है कि हमारे पास वास्तविक दुनिया कोड लिखने में कठिन समय है। यह देखते हुए कि मानक में बग को ठीक करने के लिए कितने दोष रिपोर्ट (कुछ अभी भी खुले हैं) :) उदाहरण के लिए, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#191 –

+0

@ ᐅ जोहान्सचैब -litb ᐊ वास्तव में, मुझे लगता है कि आपका हटाया गया जवाब एक अच्छा था। अगर स्थिर-स्टोरेज-अवधि ऑब्जेक्ट पूरी तरह से कन्स्ट्रक्टर कॉल से पहले मौजूद नहीं है, तो मुझे शून्य प्रारंभिकरण की कोई समझ नहीं है। जैसे, क्या यह "ऑब्जेक्ट" को एक छिपे हुए पॉइंटर के साथ प्रतिस्थापित करने के लिए एक संकलक के लिए वैध होगा जो "नया Foo()" द्वारा प्रारंभ किया जाता है? – user1998586

उत्तर

3

Defect report 1787N3914 में applied to the draft standard for C++14 में किए गए परिवर्तन की ओर ले जाता है। कौन सा बदल [dcl.init] से पैरा 12: कोई प्रारंभकर्ता एक वस्तु के लिए निर्दिष्ट किया जाता है

हैं, वस्तु है डिफ़ॉल्ट-प्रारंभ; यदि कोई प्रारंभिकता नहीं की जाती है, तो स्वचालित या गतिशील संग्रहण अवधि वाला ऑब्जेक्ट अनिश्चित मूल्य है। [नोट: स्थैतिक या थ्रेड संग्रहण अवधि वाले ऑब्जेक्ट शून्य-प्रारंभिक हैं, 3.6.2 देखें।- अंत टिप्पणी]

रहे हैं:

कोई प्रारंभकर्ता एक वस्तु के लिए निर्दिष्ट है, तो वस्तु डिफ़ॉल्ट-प्रारंभ है। जब स्वचालित या गतिशील भंडारण अवधि के साथ एक वस्तु के लिए भंडारण प्राप्त किया जाता है, वस्तु एक अनिश्चित महत्व है, और अगर कोई प्रारंभ वस्तु के लिए किया जाता है, वस्तु एक अनिश्चित मूल्य जब तक कि मूल्य बदल दिया जाता है (5.17 को बरकरार रखे हुए है कि [expr.ass])। [नोट: स्थिर या थ्रेड स्टोरेज अवधि वाले ऑब्जेक्ट शून्य-प्रारंभिक हैं, 3.6.2 [basic.start.init] देखें। अंत टिप्पणी] एक अनिश्चित मूल्य एक मूल्यांकन द्वारा निर्मित है, तो व्यवहार निम्नलिखित मामलों को छोड़कर अपरिभाषित है:

[...]

यह केवल यह स्पष्ट अनिश्चित मूल्य स्थिति बनाने के स्वचालित या गतिशील भंडारण अवधि की वस्तुओं के लिए होता है। चूंकि इसे दोष रिपोर्ट के माध्यम से लागू किया गया था, यह शायद सी ++ 11 पर भी लागू होता है क्योंकि सी ++ 14 स्वीकार किए जाने से पहले दोष रिपोर्ट की गई थी लेकिन यह आगे भी लागू हो सकती थी। एक दोष को कितना दूर करने के लिए नियम लागू किए जाने के नियम मुझे कभी स्पष्ट नहीं थे।

के बाद नियुक्ति नई टिप्पणी में लाया गया था, उसी परिवर्तन भी खंड [expr.new] संशोधित अनिश्चित मूल्य भाग एक टिप्पणी बनाने:

नए प्रारंभकर्ता शामिल न करने पर ऑब्जेक्ट डिफ़ॉल्ट है- (8.5 [dcl.init]) प्रारंभ किया गया; अगर। [नोट: यदि कोई प्रारंभिकता नहीं की जाती है, तो ऑब्जेक्ट का अनिश्चित मूल्य होता है। अंत टिप्पणी]

खंड की शुरुआत का कहना है:।

[...] एक नई अभिव्यक्ति द्वारा बनाई गई संस्थाओं गतिशील भंडारण अवधि (3.7.4) है [... ]

कौन सा खंड [dcl.init] में परिवर्तनों को लागू करने के लिए पर्याप्त लग रहे हैं।

इस परिवर्तन से पहले यह परिवर्तन भी दिलचस्प था क्योंकि C++ मानक में indeterminate value was not defined शब्द बदल गया था।

+0

इस मामले में नया शब्द अत्यंत स्पष्ट है। प्लेसमेंट-नए के लिए यह इतना स्पष्ट नहीं है (नियम जिसके लिए संग्रहण-अवधि लागू होती है?)। मेरी पढ़ाई यह है कि कोई भी पूर्व प्रारंभिक अप्रासंगिक है और व्यवहार स्वचालित/गतिशील संग्रहण अवधि के अनुसार है। उदा।, यदि आपके पास स्थिर-अवधि चार सरणी है, और उसके बाद सरणी में ऑब्जेक्ट बनाने के लिए प्लेसमेंट-नया कॉल करें, तो char सरणी का शून्य-प्रारंभिकरण अप्रासंगिक है? – user1998586

+1

@ user1998586 अद्यतन उत्तर। –

संबंधित मुद्दे