2011-12-30 10 views
25

आज मैं एक नहीं बल्कि दिलचस्प संकलक त्रुटि पर ठोकर खाई:जीसीसी में अंतर्निहित मैक्रोज़ के रूप में अनारक्षित पहचानकर्ता होने का क्या कारण है?

int main() { 
    int const unix = 0; // error-line 
    return unix; 
} 

जीसीसी 4.3.2 के साथ निम्न संदेश देता है (हाँ, प्राचीन ...):

error: expected unqualified-id before numeric constant 

जो निश्चित रूप से काफी भ्रमित है।

error: expected unqualified-id 
    int const unix = 0 
      ^
<built-in>:127:14: note: expanded from: 
#define unix 1 
      ^

मैं निश्चित रूप से unix, जो न तो अपर-केस में लिखा है उम्मीद नहीं थी और न ही अंडरस्कोर से शुरू मैक्रो होना करने के लिए:

सौभाग्य से, बजना (3.0) (हमेशा की तरह) एक छोटे से अधिक उपयोगी है , विशेष रूप से एक अंतर्निहित एक।

मैं जीसीसी में पूर्व-निर्धारित मैक्रो की जाँच की और (मेरे मंच पर) 2 देखते हैं कि का उपयोग करें "अनारक्षित" प्रतीक:

$ g++ -E -dM - < /dev/null | grep -v _ 
#define unix 1 
#define linux 1 

अन्य सभी प्रमुख अंडरस्कोर से "अच्छी तरह से व्यवहार" कर रहे हैं मैक्रो का उपयोग करते हुए परंपरागत सुरक्षित पहचानकर्ता, नमूना:

#define __linux 1 
#define __linux__ 1 
#define __gnu_linux__ 1 

#define __unix__ 1 
#define __unix 1 

#define __CHAR_BIT__ 8 
#define __x86_64 1 
#define __amd64 1 
#define _LP64 1 

(यह एक गड़बड़ है और कोई विशेष आदेश होना प्रतीत नहीं होता है ...)

इसके अलावा, "समान" के बहुत सारे हैं प्रतीकों, तो मुझे लगता है कि पिछड़े संगतता का मुद्दा है ...

तो, unix और linux मैक्रोज़ कहां से आते हैं?

+0

जीसीसी 4.7 में ठीक काम करता है, कुछ बग की तरह लगता है :) –

+0

@ श्री अनीबिस: आह अच्छा, मैं जीसीसी 4.3.2 (काम पर) का उपयोग कर रहा हूं। –

+1

मैंने ऐतिहासिक टैग जोड़ा, मुझे विश्वास है कि यह कम से कम ऐतिहासिक होगा। – Xeo

उत्तर

19

जीसीसी डिफ़ॉल्ट रूप से किसी भी सी मानक के अनुरूप नहीं है।

-ansi, -std=c99, या -std=c1x और unix साथ यह आह्वान पूर्वनिर्धारित नहीं किया जाएगा। (-std=c1x शायद हो जाएगा एक भविष्य और हाल ही में जीसीसी रिलीज में -std=c11 बन गया।)

यह थोड़ा भ्रमित है कि इस, जीएनयू पूर्वप्रक्रमक के लिए अलग मैनुअल में प्रलेखित है जीसीसी के मैनुअल में नहीं है।

जीएनयू पूर्वप्रक्रमक प्रलेखन (info cpp, संस्करण 4.5) का हवाला देते हुए:

The C standard requires that all system-specific macros be part of the "reserved namespace". All names which begin with two underscores, or an underscore and a capital letter, are reserved for the compiler and library to use as they wish. However, historically system-specific macros have had names with no special prefix; for instance, it is common to find `unix' defined on Unix systems. For all such macros, GCC provides a parallel macro with two underscores added at the beginning and the end. If `unix' is defined, `__unix__' will be defined too. There will never be more than two underscores; the parallel of `_mips' is `__mips__'.

When the `-ansi' option, or any `-std' option that requests strict conformance, is given to the compiler, all the system-specific predefined macros outside the reserved namespace are suppressed. The parallel macros, inside the reserved namespace, remain defined.

We are slowly phasing out all predefined macros which are outside the reserved namespace. You should never use them in new programs, and we encourage you to correct older code to use the parallel macros whenever you find it. We don't recommend you use the system-specific macros that are in the reserved namespace, either. It is better in the long run to check specifically for features you need, using a tool such as `autoconf'.

मैनुअल के वर्तमान संस्करण here है।

+0

कूल, तो यह वास्तव में ऐतिहासिक था! मेरे पास सटीक शक्तियां हैं! :) +1 – Xeo

+1

@Xeo: तथ्य के बाद पहचान? अब वह एक महाशक्ति है जो मैं चाहता हूं! –

+0

क्यों? मैंने बहुत पहले इस सवाल को टैग में जोड़ा था। : पी – Xeo