2012-02-06 46 views
12

मैं बनाम डिफ़ॉल्ट-initialisation मूल्य initialisation की मेरी समझ ताज़ा किया गया था, और this भर में आया था:यह सरल असाइनमेंट अपरिभाषित व्यवहार क्यों है?

struct C { 
    int x; 
    int y; 
    C() { } 
}; 

int main() { 
    C c = C(); 
} 

जाहिर है इस यूबी है क्योंकि

सी() के मामले में, वहाँ है एक कन्स्ट्रक्टर जो को एक्स और वाई सदस्यों को प्रारंभ करने में सक्षम है, इसलिए कोई प्रारंभिकता नहीं होती है। सी() को कॉपी करने का प्रयास करने के लिए इसलिए अपरिभाषित व्यवहार में परिणाम होता है।

मुझे लगता है कि मैं समझता हूं क्यों, लेकिन मैं निश्चित नहीं हूं। क्या कोई विस्तार से बता सकता है?

क्या इसका मतलब यह भी यूबी है?

int x; x = x; 

आकस्मिक रूप से, मूल्य प्रारंभिकता के संबंध में, निम्नलिखित शून्य होने की गारंटी है?

int x = int(); 
+0

सुनिश्चित नहीं है कि आपका क्या मतलब है। यदि आपका मतलब है कि x और y के मानों को अनियमित किया जाएगा तो हाँ, लेकिन आपने अपने स्वयं के प्रश्न का उत्तर दिया है (क्योंकि कन्स्ट्रक्टर इसे नहीं कर रहा है)। सी सी = सी() के लिए; मुझे लगता है कि यह पूरी तरह से मान्य है। – Sid

+0

मैंने सोचा कि यह पूरी तरह से मान्य था, जब तक कि किसी ने दावा नहीं किया। जैसा कि मैंने इसे पढ़ा है, पहला स्निपेट केवल यूबी द्वारा ही किया जा सकता है यदि दूसरा भी है, अन्यथा यह नाक संबंधी deamons के बिना, एक साधारण अनियमित मूल्य है। – spraff

+2

@ सिड: नहीं, एक अनियमित वस्तु के मूल्य का उपयोग करके अपरिभाषित व्यवहार देता है। –

उत्तर

13

आपका पहला उदाहरण व्यवहार अपरिभाषित है क्योंकि डिफ़ॉल्ट, संकलक उत्पन्न प्रतिलिपि निर्माता एक सदस्य वार नकल करेंगे, int रों फँसाने मान हो सकता है, और एक फँसाने मूल्य पढ़ने यह कार्यक्रम के क्रैश होने का कारण हो सकता है कॉपी करने के लिए।

प्रैक्टिस में, मैं कल्पना नहीं कर सकता कि यह वास्तव में कभी दुर्घटनाग्रस्त हो रहा है; कंपाइलर लगभग निश्चित रूप से प्रतिलिपि को अनुकूलित करेगा, और यदि यह नहीं हुआ है, तो यह संभवतः कुछ विशेष बिटवाई प्रतिलिपि का उपयोग करेगा जो बिना फँसाने वाले मूल्यों की जांच करेगा। (सी ++ में, आपको कॉपी बाइट्स करने में सक्षम होने की गारंटी है।)

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

तीसरे के लिए, हाँ। एक खाली पेरेंट के साथ एक प्रारंभकर्ता (और उपयोगकर्ता ने इसे ओवरराइड करने के लिए डिफ़ॉल्ट प्रारंभकर्ता को परिभाषित किया है) पहले शून्य प्रारंभिक कार्य करता है (जैसा कि स्थिर जीवनकाल वाले चर के लिए होता है)।

+0

+1, कुछ डिबगिंग टूल एप्लिकेशन को वर्चुअल मशीन में चलाते हैं जो जाल करता है (कुछ मामलों में) इसे संभावित समस्या के रूप में पहचानता है। लेकिन मैं मानता हूं कि वास्तविक मामले में परिदृश्य संभावना है कि आप केवल अनियमित स्मृति की प्रतिलिपि बना लेंगे और इसे चारों ओर ले जाएंगे। –

+0

सी ++ 14 में संदर्भ [dcl.init]/12 "] हैं यदि मूल्यांकन द्वारा एक अनिश्चित मूल्य का उत्पादन किया जाता है, तो को छोड़कर व्यवहार को अपरिभाषित किया गया है:" - और कोई भी मामला इस कोड को –

-1

नंबर क्या होगा सबसे compilers चर की बाहर अनुकूलित करेंगे है, लेकिन उन है कि नहीं है बस एक्स का मान नहीं बदलेगा। यह निम्न कोड जैसा है:

int x = 0; 
x = 0; 

ऐसा नहीं है कि दूसरी पंक्ति निष्पादित नहीं होगी, यह कुछ भी नहीं करेगी।

+0

बिंदु यह है कि यदि मेरे पोस्ट किए गए स्निपेट यूबी हैं तो संकलक अनुकूलन * किसी भी * परिणाम का कारण बन सकता है। – spraff

+3

मैं असहमत हूं, तकनीकी रूप से एक अनसेट मान से पढ़ना अनिर्धारित व्यवहार है। चाहे संकलक पढ़ने को अनुकूलित करता है * अनिश्चित व्यवहार के संभावित परिणाम का * एक * है। –

1

मुझे नहीं लगता कि यह वास्तव में undefined behavior है हालांकि c में मान unspecified values हैं। यही है, कार्यक्रम का व्यवहार तब तक परिभाषित किया जाता है जब तक आप इन अनिर्दिष्ट मानों का उपयोग नहीं करते हैं। यदि आप उनका उपयोग करते हैं, उदा। एक शर्त में या उन्हें मुद्रित करने के लिए, परिणाम परिभाषित नहीं हैं। हालांकि, मुझे नहीं लगता कि कार्यक्रम को अजीब कुछ करने की अनुमति है।

पर अंतर्निहित प्रकार, इस चल बिन्दु प्रकार के लिए इस किस्म की शून्य मान, यानी पूर्णांकों के लिए 0, 0.0 उपज के लिए, की गारंटी आदि है यह भी एक के बिना प्रकार के सदस्यों के लिए प्रदान डिफ़ॉल्ट निर्माता का उपयोग कर के संबंध में निर्माता। एक बार कोई कन्स्ट्रक्टर होने के बाद आपको अपने सदस्यों को कन्स्ट्रक्टर के बिना बनाने का ख्याल रखना होगा।

+1

ओह को कवर नहीं करता है, आप बनाम जेम्स कानज़ सीधे सीधी बंदूक में! वह कहता है कि कॉपी कन्स्ट्रक्टर अनियमित मानों का उपयोग करता है, और ऐसा करने से यूबी होता है। आप अन्यथा कहते हैं। –

+0

@SteveJessop लेकिन यह उत्तर अधिक सही लगता है, है ना? :), +1 –

+0

@ श्री अनीबिस: उच्चतम स्तर पर असहमति प्रतीत होती है जो आप सी ++ में एक अनियमित मूल्य के साथ कर सकते हैं। मानक में कुछ पाठ है जो कहता है कि आप एक लवल-रावल्यू रूपांतरण नहीं कर सकते हैं, लेकिन कोई ऐसा सोचता है कि (अन्य ऑब्जेक्ट प्रस्तुतियों के साथ आम तौर पर) आप इसे 'हस्ताक्षरित चार' के रूप में एक्सेस कर सकते हैं। व्यावहारिक रूप से, यह असंभव है कि उत्पन्न प्रतिलिपि ctor डेटा को अंधाधुंध रूप से कॉपी करने के अलावा कुछ भी करता है, लेकिन सुरक्षित खेलने के लिए मुझे विश्वास है कि जेम्स मानक परमिट के बारे में सही है। उदाहरण के लिए प्रतिलिपि समानता की जांच कर सकती है, अगर 'int' में कोई है, तो यूबी के साथ यदि वे गलत हैं। –

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