2015-07-01 22 views
21

मेरे पास निम्न कोड है।एनम प्रकार के चर के मुकाबले 'टाइपोफ एनम स्थिर' चेतावनी क्यों उत्पन्न करता है?

typedef enum {FOO, BAR} Baz; 

int main() 
{ 
    Baz f1 = FOO; 
    typeof(FOO) f2 = FOO; 
    return (f1 == f2); 
} 

gcc -Wextra foo.c का उपयोग कर मेरे संकलन एक चेतावनी कह

foo.c: In function ‘main’: 
foo.c:7:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] 
return (f1 == f2); 
      ^

मेरे जीसीसी संस्करण

gcc --version 
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2 

मैं कैसे इस समस्या को ठीक कर सकते हैं उत्पन्न करता है?

+1

http: // stackoverflow।कॉम/प्रश्न/10582523/कैसे-पूर्ण-प्रकार-रूपांतरित-निहित रूप से (खराब डुप्लिकेट हालांकि, स्वीकृत उत्तर गलत है) – Lundin

+3

यह ध्यान देने योग्य है कि 'टाइपोफ़' एक जीसीसी-विशिष्ट एक्सटेंशन है। –

उत्तर

20

C11 से, अध्याय §6.7.2.2, गणन विनिर्देशक सीधे हवाला देते हुए,

प्रत्येक enumerated प्रकार, char के साथ संगत होगा एक हस्ताक्षरित पूर्णांक प्रकार, या एक अहस्ताक्षरित पूर्णांक प्रकार। प्रकार की पसंद कार्यान्वयन-परिभाषित है।

तो, एनम वैरिएबल के प्रकार मानक द्वारा परिभाषित नहीं किया गया है। यह उपर्युक्त में से कोई भी हो सकता है।

OTOH, FOO एक गणना स्थायी किया जा रहा है, typeof(FOO) आप int, मानक जनादेश

एक पहचानकर्ता के रूप में एक घोषित गणना स्थायी टाइप int है के रूप में दे देंगे।

जिसका उपयोग f2 के प्रकार के रूप में किया जा रहा है।

अब, अगर enum unsigned int अपने कार्यान्वयन पर है, इसलिए f1 और, f2int है।

अगला, आपको चेतावनी मिलती है।

मैं इस समस्या को कैसे ठीक कर सकता हूं?

ठीक है, आप typeof(Baz) को f2 के प्रकार, जो enum के प्रकार देता है, तो दोनों f1 और f2 के प्रकार एक ही होगा बदलते हैं। कंपाइलर खुश होंगे।

SEE LIVE HERE

+0

मैंने एक मामूली अपडेट किया है। समेकित प्रकार 'char' या * किसी * हस्ताक्षरित या हस्ताक्षरित पूर्णांक प्रकार के साथ संगत हो सकता है। –

16

यह एक ज्ञात "बग" सी मानक में है। गणना स्थिरांकint प्रकार की गारंटी है, जबकि गणना चर कार्यान्वयन-परिभाषित पूर्णांक प्रकार के हैं।

See this संदर्भों के लिए।

+0

उन्होंने सामान्य प्रचार नियमों को लागू करने के बजाय ऐसा क्यों किया (यानी वे किसी भी प्रकार का हो सकते हैं जो int को बढ़ावा देता है)? – Random832

+0

@ Random832 कभी भी C90 या बाद के मानकों में कोई तर्क नहीं दिया गया था। मुझे लगता है कि वे बाइट आकार के enums की अनुमति देकर स्मृति को बचाना चाहते हैं, साथ ही सिद्धांत में यह कई मामलों में एक बाइट enum के लिए आसान होगा। अभ्यास में आप कभी भी कोड लिख नहीं सकते जो उस पर निर्भर करता है, क्योंकि ऐसा कोड गैर-पोर्टेबल होगा। यह सी मानक में वास्तव में कई बेवकूफ चीजों में से एक है, उदाहरण के लिए विभिन्न अंतर्निहित प्रकार पदोन्नति नियमों की तरह। – Lundin

+0

हाँ, लेकिन एक बाइट एक int को बढ़ावा दे सकता है। तो व्यावहारिक रूप से, लगभग किसी भी अभिव्यक्ति में खाद्य अभी भी एक int की तरह कार्य करेगा, भले ही इसका प्रकार वास्तव में enum की है। – Random832

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