2016-12-25 17 views
15

मैं निम्नलिखित कोड:सूची प्रारंभिकरण के मामले में एक संकीर्ण रूपांतरण चेतावनी क्यों दिखाई देती है?

class A 
{ 
    public: 
     A(const unsigned int val) : value(val) {} 

     unsigned int value; 
}; 

int main() 
{ 
    int val = 42; 
    A a(val); 
    A b{val};  // <--- Warning in GCC, error in Microsoft Visual Studio 2015 

    return 0; 
} 

क्यों संकुचन रूपांतरण चेतावनी केवल सूची आरंभीकरण उपयोग के मामले में दिखाई देता है?

उत्तर

17

list initialization सी ++ 11 के बाद से अंतर्निहित प्रकारों के बीच निहित संकीर्ण रूपांतरणों को प्रतिबंधित करने वाली सुविधा के साथ पेश किया गया था। इसी समय, अन्य दो "पुरानी शैली" (के बाद से सी ++ 98) प्रारंभ रूपों जो

int val = 42; 
A a(val); 
A a = val; 

तरह कोष्ठकों और समान-चिह्न का उपयोग सूची आरंभीकरण साथ समझौते के लिए उनके व्यवहार में परिवर्तन नहीं करते, क्योंकि जो विरासत कोड अड्डों के बहुत सारे तोड़ सकता है।

+2

क्या उस निषेध को लगातार लागू करने के लिए एक कंपाइलर ध्वज है? – Schwern

+0

'int i = 0; चार सी [] = {i}; 'पुराना शैली प्रारंभिक रूप भी था, वैध सी ++ 03 लेकिन अमान्य सी ++ 11 था। विरासत कोड * वास्तव में परिवर्तन से टूट गया था। – hvd

9

मानक के तहत, उस संदर्भ में संकुचित रूपांतरण अवैध हैं। वे अन्य संदर्भ में कानूनी हैं। ("अवैध" से, मेरा मतलब है कि कार्यक्रम को खराब बना दिया गया है)।

मानक के लिए आवश्यक है कि एक कंपाइलर उस विशेष मामले में निदान जारी करे (कार्यक्रम को खराब बनाये)। नैदानिक ​​उत्सर्जित मानक पत्तियों को अपरिभाषित करने के बाद संकलक क्या करता है।

एमएसवीसी संकलन को रोकने का विकल्प चुनता है। जीसीसी emit nasal राक्षसों को चुनता है प्रोग्राम का अर्थ है समझ में आता है, और रूपांतरण करते हैं, और संकलन जारी रखते हैं।

दोनों चेतावनियां और त्रुटियां डायग्नोस्टिक्स हैं जहां तक ​​मानक का संबंध है। पारंपरिक रूप से त्रुटियां होती हैं जिन्हें आप डायग्नोस्टिक्स कहते हैं जो संकलक रोकने वाले संकलन को आगे बढ़ाते हैं।

यह भी ध्यान रखें कि कंपाइलर्स जब चाहें निदान को मुक्त करने के लिए स्वतंत्र होते हैं।

पारंपरिक रूप से चेतावनी का उपयोग तब किया जाता है जब आप मानक निर्देशों को एक अच्छी तरह से गठित कार्यक्रम करते हैं, फिर भी संकलक लेखकों को बीमार सलाह दी जाती है, और जब मानक एक बीमार गठित कार्यक्रम का पता लगाता है, तो त्रुटियां होती हैं, लेकिन अधिकांश कंपाइलर सख्ती से इसे लागू नहीं करते हैं।

+3

जब तक सी 99 ने # आतंकवादी निर्देश नहीं जोड़ा, तब तक एक कार्यान्वयन किसी भी स्रोत टेक्स्ट को देखने से पहले "यह एक निदान" है, बिना किसी शर्त के डायग्नोस्टिक्स के लिए सभी आवश्यकताओं को संतुष्ट कर सकता था। मानक # आतंक निर्देश को अधिक स्पष्ट रूप से परिभाषित करता है, लेकिन फिर भी अन्य सभी आवश्यकताओं को बेकार रूप से अस्पष्ट छोड़ देता है। – supercat

0

चेतावनी के पीछे कारण पहले से ही अन्य उत्तरों द्वारा समझाया गया है।

इस चेतावनी/त्रुटि को ठीक करने का तरीका है। एक कन्स्ट्रक्टर बनाएं जो तर्ककर्ता के रूप में startizer_list लेता है।

A(std::initializer_list<int> l) : value(*(l.begin())) { 
    cout << "constructor taking initializer list called\n"; 
} 
+2

यह "फिक्स" गैरकानूनी है। 'Int val = 0 की अनुमति देने के लिए; एक बी {वैल}; ', आप' ए बी 1 {1,2,3,4,5}; 'को अनुमति देने वाले कोड जोड़ते हैं और' अस्वीकृत int val = 42 को अस्वीकार करते हैं; एक सी {वैल}; '। –

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