2012-05-05 7 views
9

मैं कोड निम्नलिखित है:जीसीसी क्यों चेतावनी नहीं देता है जब एक enum या int मान को फ़ंक्शन के तर्क के रूप में पारित किया जाता है जो बूल है?

typedef enum 
{ 
    FOO, 
    BAR, 
    BAZ 
} foo_t; 

static void afunc(bool is_it_on) 
{ 
    /* do the job */ 
} 

int main(void) 
{ 
    afunc(BAZ); 
    return 0; 
} 

इस कोड संकलन भी -Wall -Wextra विकल्पों संकलक करने के लिए दिया के साथ किसी भी चेतावनी संदेश उत्पन्न नहीं करता है,। मैंने -Wconversion विकल्प के साथ भी कोशिश की है, जिसने कोई प्रभाव नहीं लिया क्योंकि bool और enum g ++ के लिए समान आकार का प्रतीत होता था। (enum का आकार विनिर्देश में परिभाषित नहीं किया गया है, जहां तक ​​मुझे पता है)

मैंने जीसीसी मैनुअल के माध्यम से कॉम्बेड किया है और इसके बारे में कुछ भी नहीं मिला है।

सवाल:

  • वहाँ इस तरह के मामलों में एक चेतावनी उत्पन्न करने के लिए संकलक मजबूर करने के लिए एक तरीका है?
  • या यह है कि यह अंतर्निहित कास्टिंग सी ++ विनिर्देश द्वारा कानूनी है?

संकलक है कि मैं उपयोग कर रहा हूँ: जीसीसी 4.1.2


उसे संपादित

निष्कर्ष:

इसका एकमात्र व्यवहार्य समाधान का प्रतिनिधित्व करने के लिए एक नए प्रकार परिभाषित करने के लिए लगता है 0 या 1, और bool के बजाय इसका उपयोग करें।

कोड निम्नलिखित की तरह होगा, और जी ++ जैसे रूपांतरण के बारे में शिकायत:

typedef enum 
{ 
    FOO1, 
    FOO2 
} foo_t; 

typedef enum 
{ 
    MY_FALSE, 
    MY_TRUE 
} my_bool_t; 

void foo(my_bool_t a) 
{ 
} 

int main(void) 
{ 
    /* 
     * gcc generates an error. 
     * error: cannot convert ‘foo_t’ to ‘my_bool_t’ 
     * for argument ‘1’ to ‘void foo(my_bool_t)’ 
     */ 
    foo(FOO1); 
    return 0; 
} 
+1

क्योंकि सी ++ ' टाइप सिस्टम केवल उपयोगकर्ता द्वारा परिभाषित प्रकारों के लिए अच्छा है, अंतर्निहित प्रकारों के लिए यह हमेशा बेकार है। इसकी विरासत का परिणाम। –

+0

हां ऐसा लगता है।मैंने केवल 0 या 1 का प्रतिनिधित्व करने के लिए समर्पित एक नया प्रकार टाइप करने का निर्णय लिया है, और _true_ या _false_ को व्यक्त करने के उद्देश्य से बूल के बजाय इसका उपयोग करें। – orchistro

उत्तर

10

हाँ, उन अंतर्निहित रूपांतरण पूरी तरह से कानूनी है।

सी ++ 11 मसौदा n3290, §4.12 बूलियन रूपांतरण:

गणित, unscoped गणन, सूचक, या सूचक सदस्य प्रकार के एक prvalue प्रकार bool के prvalue में बदला जा सकता। शून्य मान, शून्य सूचक मान, या शून्य सदस्य सूचक मान को गलत में परिवर्तित किया जाता है; कोई अन्य मूल्य सत्य में परिवर्तित हो गया है। प्रकार std :: nullptr_t का एक प्रसार प्रकार बूल के प्रसार में परिवर्तित किया जा सकता है; परिणामस्वरूप मूल्य गलत है।

इन रूपांतरणों (अंकगणितीय प्रकारों के लिए) पर चेतावनी शायद पूरे स्थान पर चेतावनियों की बड़ी संख्या का कारण बनती है, मुझे नहीं लगता कि यह प्रबंधनीय होगा।

सी ++ 11 में, आप उपयोग कर सकते हैं enums scoped कि अंतर्निहित रूपांतरण को रोकने के लिए:

यह Foo से bool में रूपांतरण की कमी के लिए संकलित करने के लिए विफल रहता है:

enum class Foo { ONE }; 

void tryit(bool b) { } 

int main() 
{ 
    tryit(Foo::ONE); 
} 
+0

धन्यवाद, मैट। यदि यह सी ++ विनिर्देशन द्वारा कानूनी है, तो मुझे लगता है कि जो कुछ मैं चाहता हूं उसे प्राप्त करने का एकमात्र तरीका सिर्फ परियोजना के लिए एक नया बूलियन प्रकार टाइप करना है ताकि परियोजना के सदस्य कोड स्निपेट जैसी गलतियों को न करें। – orchistro

+0

अफसोस की बात है, जीसीसी 4.1.2 'scoped enums' का समर्थन नहीं कर रहा है। मुझे लगता है कि मुझे टाइपपीफ समाधान का सहारा लेना चाहिए, और यह वास्तव में काम करता है। आम तौर पर, आपको इसकी आवश्यकता नहीं है। लेकिन कुछ परिस्थितियों में आप अन्य लोगों के कोड को दोबारा कर रहे हैं, इस 'सख्त' प्रकार की जांच के बिना, आपको खेद होगा। शायद मुझे लिंट का उपयोग करना चाहिए था। – orchistro

+0

@orchistro: यदि संभव हो, तो gcc पर एक नए संस्करण पर जाने का प्रयास करें (मुझे पता है कि यह आसान नहीं है ...)। जीसीसी 4.1.x काफी पुरानी शाखा है। –

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

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