2012-12-16 29 views
7

सी ++ 11 मानक 8.5.4.3 कहता है:वीसी ++ की एक बड़ी बग? प्रारंभकर्ता-सूची क्यों मूल्य-प्रारंभिक संरचना को प्रारंभ नहीं करती है?

"अगर प्रारंभकर्ता सूची में कोई तत्व नहीं है और टी डिफ़ॉल्ट कन्स्ट्रक्टर वाला क्लास प्रकार है, तो ऑब्जेक्ट वैल्यू-प्रारंभिक है।"

struct A 
{ 
    int get() { return i; } 

private: 
    int i; 
}; 

int main() 
{ 
    A a = {}; 

    int n = a.get(); 
    cout << n << endl; 
    // n is a random number rather than 0 

    return 0; 
} 

क्या यह वीसी ++ का एक बग है? मेरा वीसी ++ नवीनतम नवंबर 2012 सीटीपी है।

+0

कंपाइलर अनुकूलन सी ++ मानक के प्रावधान को तोड़ना नहीं चाहिए। तो मुझे लगता है कि इसका अनुकूलन करने के लिए कुछ भी नहीं है। – xmllmx

+0

@ किलियनडीएस, कृपया मेरी संशोधित पोस्ट – xmllmx

+0

की समीक्षा करें यदि आप 'std :: cout << n << std :: endl;' जोड़ते हैं तो मुद्रित क्या होता है? – helium

उत्तर

3

गैर-समेकित वर्ग प्रकार का मूल्य-प्रारंभिक 8.5p8 द्वारा कवर किया गया है। आपके मामले में (गैर-संघ) वर्ग में एक निहित रूप से घोषित डिफ़ॉल्ट डिफ़ॉल्ट डिफ़ॉल्ट पैरामीटर कन्स्ट्रक्टर (12.1p5) है, जो हटाया नहीं गया है और छोटा (ibid) है। इस प्रकार 8.5p8 की दूसरी बुलेट लागू होता है:

- अगर T (संभवत: सीवी-योग्य) गैर संघ वर्ग एक उपयोगकर्ता द्वारा प्रदत्त या नष्ट कर दिया डिफ़ॉल्ट निर्माता के बिना प्रकार है, तो वस्तु शून्य आरंभ नहीं हो जाता और, यदि T में एक गैर-मामूली डिफ़ॉल्ट कन्स्ट्रक्टर है, तो डिफ़ॉल्ट-प्रारंभिक;

तो A शून्य-प्रारंभिक होना चाहिए, और कार्यक्रम को 0 प्रिंट करना चाहिए।

निम्नलिखित कार्यक्रम पर:

struct A { int get() { return i; } private: int i; }; 
#include <iostream> 
int main() { 
    char c[sizeof(A)]; 
    new (c) int{42}; 
    std::cout << (new (c) A{})->get() << '\n'; 
} 

जीसीसी-4.7.2 सही ढंग से आउटपुट 0; gcc-4.6.3 गलत तरीके से आउटपुट 42; क्लैंग-3.0 पूरी तरह पागल हो जाता है और कचरा आउटपुट करता है (उदा। 574874232)।

+0

चूंकि शून्य-या डिफ़ॉल्ट-कक्षा शुरू करने के बाद से किसी भी अन्य-प्रारंभिक सदस्यों को स्पर्श किया जाता है? –

+0

@LightnessRacesinOrbit कम से कम C++ 11 ** [dcl.init] **/5: "* [...] - यदि टी एक (संभवतः सीवी-योग्य) गैर-यूनियन क्लास प्रकार है, प्रत्येक गैर स्थैतिक डेटा सदस्य और प्रत्येक बेस-क्लास सबोबजेक्ट शून्य-प्रारंभिक है और पैडिंग शून्य बिट्स में प्रारंभ किया गया है; [...] * " – ecatmur

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

  • कोई संबंधित समस्या नहीं^_^