2015-01-07 1 views
7

निम्न की तरह कुछ के लिए परिभाषित व्यवहार क्या है?परिवर्तनीय नामक के रूप में नामित

#include <stdio.h> 

typedef enum { 
    ENUM_VAL_1 = 1, 
    ENUM_VAL_2 = 2 
} TEST_ENUM; 

int main() { 
    TEST_ENUM testVar1 = ENUM_VAL_1; 
    TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1; 
    TEST_ENUM testVar2 = ENUM_VAL_1; 

    printf("ENUM_VAL_1 = %u\n",ENUM_VAL_1); 
    printf("testVar1 = %u\n",testVar1); 
    printf("testVar2 = %u\n",testVar2); 

    return 0; 
} 

दोनों जीसीसी और MSVC compilers के साथ अपने परीक्षण से, इस के व्यवहार testVar1 गणन मान "ENUM_VAL_1" या 1. हालांकि करने के लिए बराबर का गठन किया जाएगा जो है, अगले स्टेटमेंट चर ENUM_VAL_1 सेट करने की कोशिश करेंगे अपने मूल्य के बराबर, जो वर्तमान में अनियमित और इस प्रकार कचरा है, वैरिएबल ENUM_VAL_1 को गणना मूल्य ENUM_VAL_1 के बराबर सेट करने के बजाय। फिर, ज़ाहिर है, testVar2 को वैरिएबल ENUM_VAL_1 के समान कचरा मूल्य भी मिलेगा।

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

धन्यवाद!

+1

आप शब्द प्रगणक के लिए शब्द गणना प्रतिस्थापन विषय के शीर्षक अद्यतन करना चाहिए। –

उत्तर

6
सी मानक (पहचानकर्ता के 6.2.1 कार्यक्षेत्र)

    के अनुसार

  1. ... एक पहचानकर्ता एक ही नाम अंतरिक्ष, स्कोप में दो अलग अलग संस्थाओं में नामित हैं ओवरलैप हो सकता है। यदि ऐसा है, तो एक इकाई का दायरा (आंतरिक दायरा) अन्य इकाई (बाहरी दायरे) के दायरे से पहले सख्ती से समाप्त हो जाएगा। आंतरिक दायरे में, पहचानकर्ता आंतरिक दायरे में घोषित इकाई को निर्दिष्ट करता है; बाह्य दायरे में घोषित इकाई आंतरिक दायरे में छुपा हुआ है (और दिखाई नहीं दे रहा है)।

और

7 संरचना, संघ, और गणन टैग कि सिर्फ एक प्रकार निर्दिष्टकर्ता कि टैग वाणी में टैग की उपस्थिति के बाद शुरू होता गुंजाइश है। प्रत्येक गणना निरंतर गुंजाइश है जो के बाद एक गणक सूची में परिभाषित गणनाकर्ता की उपस्थिति के ठीक बाद शुरू होती है।किसी भी अन्य पहचानकर्ता कि सिर्फ अपने declarator

के पूरा होने के बाद शुरू होता है तो यह घोषणा

TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1; 

declarator ENUM_VAL_1 से पहले संकेत = पूरा माना जाता है में गुंजाइश है। तो यह गणनाकर्ता छुपाता है।

वास्तव में यह स्वयं ही शुरू होता है और इसका अनिश्चित मूल्य होता है।

एक ही सी के लिए मान्य है ++ (घोषणा के 3.3.2 प्वाइंट)

1 एक नाम के लिए घोषणा की बात अपने पूरा declarator (क्लॉज 8) के बाद और उसके प्रारंभकर्ता से ठीक पहले है (यदि कोई हो), जैसा कि नीचे बताया गया है। [उदाहरण:

int x = 12; 
{ int x = x; } 

यहाँ दूसरा एक्स अपने स्वयं के (अनिश्चित) मूल्य के साथ आरंभ नहीं हो जाता। अंत उदाहरण]

+0

बहुत पूर्ण और संपूर्ण उत्तर - धन्यवाद! –

3

मुझे संकलन करने में विफल होने के लिए TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1; लाइन की उम्मीद है, लेकिन ऐसा करता है। मैंने असाइन किए गए मान को ENUM_VAL_2 पर बदल दिया, और प्रिंटिंग ENUM_VAL_1 = 2, testVar1 = 1 और testVar2 = 2 देता है, इसलिए ENUM_VAL_1 एक स्थानीय चर है।

यह वास्तव में एक नियमित स्कोपिंग मुद्दा है; इसका मतलब है कि main() में परिवर्तनीय घोषणा — के बाहर घोषणा को छाया देती है और typedefmain() के भीतर थी, तो कोड संकलित नहीं होगा। छायांकन देखने के लिए अपने संकलन विकल्पों में -Wshadow जोड़ें। testVar1 सेट करने के बाद, ENUM_VAL_1 का मतलब स्थानीय चर है, न कि गणना निरंतर। अपने साथ एक चर शुरू करना वास्तव में चर को प्रारंभ नहीं करता है; यह मूल्य में अपरिभाषित कचरा प्रतिलिपि बनाता है।

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