2013-03-08 14 views
5

-Wall -pedanticबजना enum अतिप्रवाह

#include <limits.h> 
#include <stdio.h> 

int main(void) 
{ 
    enum x { 
     a, 
     max = INT_MAX, 
     out_1 
    }; 
    enum y { 
     b, 
     out_2 = INT_MAX + 1 
    }; 


    printf("%d %d\n", out_1, out_2); 
    return 0; 
} 

बजना का उपयोग करना रिटर्न

demo.c:9:3: warning: overflow in enumeration value 
       out_1 
       ^

आप देख सकते हैं, संकलक out_2 अतिप्रवाह के बारे में चेतावनी नहीं करता है, उसका मूल्य संकलन समय पर अज्ञात है?

+2

बहुत यकीन है कि मानक 'enum' की सीमा को परिभाषित नहीं करता है। – asveikau

+1

मेरा अनुमान है: यह पहले INT_MAX + 1 का मूल्यांकन करता है, जो चारों ओर लपेटता है और आउट 2 को असाइन करता है। –

+1

@ जॉनी: नहीं, यह यूबी का आह्वान करता है। –

उत्तर

1

पहले उदाहरण में, संकलक स्वयं एक पूर्णांक चुनने की कोशिश कर रहा है जो अतिप्रवाह पैदा कर रहा है, और इसलिए आपको चेतावनी दी जा रही है। यह INT_MIN उत्पादन कर रहा है। मानक signed int में किसी भी मान को स्थिरता के लिए अनुमति देता है (नीचे देखें)।

दूसरे में, (INT_MAX + 1) अभिव्यक्ति की गणना out_2 को सौंपी जाने से पहले की जाती है। अभिव्यक्ति में एक अतिप्रवाह एक परिणाम उत्पन्न कर रहा है जिसकी अनुमति है, लेकिन यह अपरिभाषित व्यवहार है। वैध परिणाम तब enum में संग्रहीत किया जाता है, यही कारण है कि पहली त्रुटि उत्पन्न नहीं होती है।

बजना (3.2) भी इस बारे में चेतावनी नहीं होगा, जो प्रभावी रूप से समान होता है:

int a = INT_MAX + 1; 

इस संबंध में, बजना सी मानक के अनुसार व्यवहार नहीं कर रहा है, के रूप में यह अनिर्धारित रहता है।

तुलना में जीसीसी से उत्पादन अंतर पूरी तरह से स्पष्ट करता है:

In function ‘main’: 
9:9: error: overflow in enumeration values 
13:25: warning: integer overflow in expression [-Woverflow] 

इंटेल संकलक enum अतिप्रवाह पर ध्यान नहीं देता है, लेकिन पूर्णांक अतिप्रवाह के बारे में चेतावनी देते हैं:

enum.c(13): warning #61: integer operation result is out of range 
     out_2 = INT_MAX + 1 
        ^


संदर्भ के लिए, सी 99 मानक 6.7.7.2.2 से, "अभिव्यक्ति जो एक गणना निरंतर मान के मूल्य को पूर्ण करती है वह एक पूर्णांक निरंतर अभिव्यक्ति होगी जिसका मूल्य int; .3," टी के रूप में दर्शाया जा सकता है वह एक गणक सूची में पहचानकर्ताओं को स्थिरांक के रूप में घोषित किया जाता है जिनके पास टाइप int है और जहां भी इसकी अनुमति है वहां दिखाई दे सकता है। "यानी एक enum स्थिर int मान हो सकता है, और int प्रकार है। परिभाषित एनम वैरिएबल के परिणामी प्रकार char, int या unsigned int हो सकते हैं, जब तक यह enum में सभी संभावित स्थिरांक के लिए अनुमति देता है। उदाहरण के लिए enums उदाहरण में अपरिभाषित हैं, क्योंकि दोनों को एक पूर्णांक ओवरफ़्लो की आवश्यकता होती है। पहला स्पष्ट रूप से अवैध है।

+0

लेकिन सवाल यह था: क्यों Clang ** ** ** के बारे में चेतावनी नहीं देता है। –

+0

@eznme: दूसरा बिंदु - अभिव्यक्ति की गणना के बाद पूर्णांक एक वैध enum है, इस उदाहरण में। – teppic

+1

@eznme मुझे लगता है कि ऐसा इसलिए है क्योंकि '-वॉल' एक गलत नाम है। '-वेरथिंग'' या शायद '-वेक्स्ट्रा' के साथ, मैं क्लैंग को अतिप्रवाह के बारे में चेतावनी देने की अपेक्षा करता हूं। –

0

आईएसओ सी पूर्णांक के रूप में पूर्णांक निर्दिष्ट करता है।

यदि आपका कंपाइलर इसे (और जीसीसी और क्लैंग डू करता है) तो INT_MIN एक बिल्कुल सही मूल्य है।

संकलक एक निर्दिष्ट सूचकांक तो यह आवश्यक है इस मुद्दे को एक त्रुटि की अनुमति नहीं होगी।

कारण है कि एक स्पष्ट अनुरोध किया INT_MIN ठीक है पर INT_MAX पूर्ववर्ती से एक स्वत: बढ़े हुए मूल्य जारी एक चेतावनी है, कि मानक +1 व्यवहार की आवश्यकता है।

+0

लेकिन 'enum' स्थिरांक' int' हैं। – ouah

+0

@उह हाँ जैसा मैंने कहा था। (मैंने उपयोग किया चौथा शब्द) –

+0

ताकि आप सभी सी कंपाइलर्स द्वारा 'INT_MIN' के' enum' निरंतर स्वीकार कर सकें? – ouah