2015-01-02 11 views
17

इस कोड स्निपेट पर विचार करें:अजीब अप्रारंभीकृत स्थिरांक सदस्य व्यवहार

struct Foo { 

}; 

template<typename T> 
struct Bar { 
    const T foo; 
}; 

int main() { 
    Bar<Foo> test; 
} 

मैं जी के साथ यह संकलन कर रहा हूँ ++ - 4.9.2 के साथ [-std = C++ 11 -O0 -g3 -pedantic -Wall -Wextra -Wconversion] और error: uninitialized const member in ‘struct Bar<Foo>’ हो रही है। यह बहुत स्पष्ट है।

लेकिन केवल std :: स्ट्रिंग को Foo सदस्य और प्रोग्राम संकलन के रूप में जोड़ने का प्रयास करें!

#include <string> 
struct Foo { 
    std::string test; 
}; 
// (...) 

क्या हो रहा है? फिर से संकलित करने में विफल होने के लिए परीक्षण के प्रकार को डबल कारण प्रोग्राम में बदलना। वर्ग में कौन सी स्ट्रिंग सदस्य बदलता है?

Link to online compiler with this snippet.

ऐसा लगता है कि जीसीसी संस्करण 4.6 के बाद से इस तरह व्यवहार करता है।

+7

एक जीसीसी बग बजना होने के लिए लगता है शेयर नहीं करता है: http: //coliru.stacked-crooked। com/a/508312aef603cc15 – Deduplicator

+0

प्रारंभिकता हालांकि यह कुछ याद आ रही चेतावनी है लेकिन [-O0 -g3 -pedantic -Wall -Wextra -Wconversion] जोड़ना कोई और कंपाइलर संदेश नहीं देता है। – omikron

+0

एमएसवीसी समस्या को प्रदर्शित नहीं करता है और डिफ़ॉल्ट कन्स्ट्रक्टर की कमी के लिए संकलन करने से इंकार कर देता है। –

उत्तर

17

मुझे लगता है कि यह लगातार एक त्रुटि उत्पन्न करना चाहिए। क्लेंग ऐसा करता है। सी ++ मानक §12.1.4 के खंड (4.3) कि डिफ़ॉल्ट निर्माता परोक्ष हटा दी जाती है में कहते हैं जब

- स्थिरांक योग्य प्रकार के किसी भी गैर संस्करण गैर स्थैतिक डेटा सदस्य (या सरणी क्या है) कोई ब्रेस-या बराबर-प्रारंभकर्ता के साथ एक उपयोगकर्ता द्वारा प्रदान की डिफ़ॉल्ट निर्माता नहीं है,

Foo के रूप में एक उपयोगकर्ता द्वारा प्रदान की डिफ़ॉल्ट निर्माता नहीं है, Bar एक परोक्ष नष्ट कर दिया डिफ़ॉल्ट निर्माता होनी चाहिए और इस प्रकार में Bar<Foo> test instantiating मुख्य एक त्रुटि उत्पन्न करना चाहिए।

शायद जीसीसी को एक बग की रिपोर्ट करें?

4

यदि आपके पास अपनी कक्षा/संरचना में const डेटा सदस्य है, तो उसके लिए संकलक डिफ़ॉल्ट कन्स्ट्रक्टर उत्पन्न नहीं करेगा। आपको इसे स्पष्ट रूप से परिभाषित करना होगा और const सदस्य प्रारंभ करना होगा (इसे असाइन नहीं करें)।

यह दोनों मामलों में एक त्रुटि होनी चाहिए।

+4

यह सवाल का जवाब नहीं दे रहा है। यदि 'stoo :: string' डेटा सदस्य' Foo' में जोड़ा गया है तो यह संकलित क्यों होता है। – juanchopanza

+0

'बार' में' const' डेटा सदस्य 'Foo' है। – juanchopanza

+0

@ravi: 'Foo' स्ट्रिंग पैरामीटर में जोड़े जाने की स्थिरता कोई फर्क नहीं पड़ता। 'बार' में 'कॉन्स फू' है। – omikron

2

ऐसा लगता है कि g ++ स्वचालित रूप से एक डिफ़ॉल्ट कन्स्ट्रक्टर उत्पन्न करता है, भले ही सदस्यों को निर्माण समय पर प्रारंभ किया जाना चाहिए क्योंकि यह जानता है कि एक स्ट्रिंग में एक डिफ़ॉल्ट स्ट्रिंगर है जो इसे खाली स्ट्रिंग में प्रारंभ कर रहा है। असल में ऐसा होता है जैसे स्रोत था:

struct Foo { 
    std::string test; 
    Foo():test() {;} 
}; 

template<typename T> 
struct Bar { 
    const T foo; 
    Bar(): foo() {;} 
}; 

int main() { 
    Bar<Foo> test; 
} 

जो क्लैंग और एमएसवीसी दोनों के साथ ठीक से संकलित करता है।

(लेकिन मैं मानता चाहिए मैं अभी भी है कि समझा जीसीसी दस्तावेज़ में संदर्भ नहीं मिला है ...)

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