2015-09-27 8 views
5

संकलित करता है और काम करता है, जहां तक ​​मुझे पता है, आप केवल अपनी घोषणा if they are integral types की उसी पंक्ति में स्थिर कॉन्स सदस्यों को प्रारंभ कर सकते हैं। हालांकि, मैं अभी भी प्रारंभ और कुछ स्थिर स्थिरांक का उपयोग करने में सक्षम था दोगुना हो जाता है:गलत स्थिर कॉन्स प्रारंभिकरण जो

// compiles and works, values are indeed doubles 
struct Foo1{ 
    static const double A=2.5; 
    static const double B=3.2; 
    static const double C=1.7; 
}; 

// compiles, but values are cast to int 
struct Foo2{ 
    static const int A=2; 
    static const int B=3; 
    static const double C=B/A; //becomes 1 
}; 

// does not compile, Foo3::B cannot appear in a constant-expression 
struct Foo3{ 
    static const int A=2; 
    static const double B=3; 
    static const double C=A/B; 
}; 

// does not compile, a cast to a type other than an integral or enumeration 
// cannot appear in a constant-expression 
struct Foo4{ 
    static const int A=2; 
    static const int B=3; 
    static const double C=(double)A/B; 
}; 

foo2 संकलित लेकिन foo2 :: सी 1 हो जाता है, तो शायद यह के रूप में यह संख्यानुसार एक है एक पूर्णांक के रूप में व्यवहार किया जाता है। Foo3 और Foo4 अपेक्षा के अनुसार भी संकलित नहीं करते हैं। हालांकि, मुझे समझ में नहीं आता क्यों Foo1 दोनों संकलित और सही तरीके से काम करता है। क्या यह विशिष्ट उपयोग स्वीकार किया जाता है? क्या यह कुछ अनुकूलन के कारण है? (मैंने -O1 और -O0 का उपयोग करने का प्रयास किया है)

नोट: जीएमयू 5.2.0 का उपयोग सेमेक के साथ और मानक को सी ++ 98 में सेट करना। सी ++ 11 पर स्विचिंग ठीक काम करता है (यानी, संकलित नहीं होता है और उन सदस्यों को constexpr पर स्विच करने के लिए कहता है)।

+1

'-pedantic' स्विच जोड़ें, फिर जीसीसी भी 'Foo1' के बारे में शिकायत करेगा। http://melpon.org/wandbox/permlink/o35cpEXlgMedfvMT – dyp

उत्तर

11

Foo1 मामले वास्तव में गैर-अनुरूप और अगर हम -std=c++98 -pedantic जीसीसी का उपयोग कर निर्माण इस प्रकार चेतावनी देगा (see it live):

error: floating-point literal cannot appear in a constant-expression 
static const double A=2.5; 
        ^
warning: ISO C++ forbids initialization of member constant 'Foo1::A' of non-integral type 'const double' [-Wpedantic] 

जबकि -pedantic बिना संकलन किसी भी त्रुटि उपज नहीं करता है या चेतावनी (see it live)

तो यह एक विस्तार होना चाहिए और यदि हम -std=C++98 -pedantic का उपयोग करके क्लैंग का उपयोग करते हैं तो हम यह संदेश देखते हैं:

warning: in-class initializer for static data member of type 'const double' is a GNU extension [-Wgnu-static-float-init] 
static const double A=2.5; 
        ^~~~ 

जो यह पुष्टि करता है कि यह एक विस्तार है।

सी ++ 11 में संगत रहने के लिए फ्लोटिंग पॉइंट पर यह प्रतिबंध सी ++ 11 में रखा गया था और कॉन्स्टेक्सप्र के निरंतर उपयोग को प्रोत्साहित करने के लिए: Constant expression initializer for static class member of type double

यह भी Foo2C आरंभ के लिए मामला एक विस्तार के रूप अनुमति दी है है, विभाजन का परिणाम पूर्णांक हो जाएगा के बाद से परिणाम के प्रकार ऑपरेंड के प्रकार पर निर्भर करता है और आप क्या आवंटित पर निर्भर नहीं करता यह करने के लिए।

अद्यतन

यह एक depreciated extension है:

जी ++ अनुमति देता है स्थिरांक फ्लोटिंग प्वाइंट प्रकार के स्थिर डेटा सदस्यों को एक वर्ग परिभाषा में एक प्रारंभकर्ता साथ घोषित किया जाना है। मानक केवल कॉन्स अभिन्न प्रकारों और स्थिर गणना प्रकारों के स्थिर सदस्यों के लिए प्रारंभकर्ताओं को अनुमति देता है, इसलिए इस एक्सटेंशन को हटा दिया गया है और भविष्य के संस्करण से हटा दिया जाएगा।

एक और विस्तृत gcc bug report है जो विस्तार और इसके आसपास के अन्य संबंधित मुद्दों की वैधता पर चर्चा करता है।

यह अजीब लग रहा था कि -pedantic का उपयोग करके इसे एक त्रुटि में बदलने के लिए पर्याप्त था, gcc bug report that covers that है।

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