2014-06-26 7 views
12

Wiki का कहना है:घोषणापत्र के साथ बाहरी चर को परिभाषित करने के लिए कैसे?

extern कीवर्ड का अर्थ है "को परिभाषित करने के बिना घोषित"। दूसरे शब्दों में, यह स्पष्ट रूप से एक चर घोषित करने का तरीका है, या परिभाषा के बिना घोषणा को मजबूर करने का एक तरीका है। एक चर को स्पष्ट रूप से परिभाषित करना भी संभव है, यानी परिभाषा को मजबूर करने के लिए। यह एक वैरिएबल पर प्रारंभिक मान निर्दिष्ट करके किया जाता है।

इसका मतलब है, एक extern घोषणा कि चर initializes कि चर के लिए एक परिभाषा के रूप में कार्य करता है। तो,

/* Just for testing purpose only */ 
#include <stdio.h> 
extern int y = 0; 
int main(){ 
    printf("%d\n", y); 
    return 0; 
} 

मान्य होना चाहिए (compiled in C++11)।

[Warning] 'y' initialized and declared 'extern' [enabled by default] 

जो नहीं करना चाहिए: लेकिन जब जीसीसी 4.7.2 में विकल्प -Wall -Wextra -pedantic -std=c99 साथ संकलित, एक चेतावनी पैदा करता है। AFAIK,

extern int y = 0; 

प्रभावी रूप से

int i = 0; 

रूप में एक ही गलत यहाँ क्या हो रहा है है?

+3

[यह] (http://stackoverflow.com/questions/4268589/warning-in-extern-declaration) भी मदद कर सकता है। स्वीकार्य उत्तर नहीं, लेकिन [एंड्रीटी] द्वारा एक (http://stackoverflow.com/users/187690/andreyt)। नोट विशेष रूप से जवाब की अंतिम पंक्ति: _Just संकलक सेटिंग्स में इस चेतावनी को निष्क्रिय (और, कृपया, जीसीसी टीम को इसके बारे में एक असभ्य पत्र लिखने) ._ – devnull

+0

@devnull; हाँ .. – haccks

+0

@devnull; आदमी। तुमने मुझे बचाया। मैं इसके बारे में एक घंटे के बारे में गड़बड़ कर रहा था! बहुत बहुत धन्यवाद :) – haccks

उत्तर

5

मानक के सभी तीन संस्करणों - आईएसओ/आईईसी 9899: 1990, आईएसओ/आईईसी 9899: 1999 और आईएसओ/आईईसी 9899: 2011 - शीर्षक के साथ खंड में एक उदाहरण दिया बाहरी वस्तु परिभाषाओं (§ सी 9 0 के 6.7.2, और §6.9।C99 और सी 11) है जो दिखाता है की 2:

उदाहरण 1

int i1 = 1;  // definition, external linkage 
static int i2 = 2; // definition, internal linkage 
extern int i3 = 3; // definition, external linkage 
int i4;   // tentative definition, external linkage 
static int i5;  // tentative definition, internal linkage 

उदाहरण जारी है, लेकिन extern int i3 = 3; लाइन स्पष्ट रूप से पता चलता मानक इंगित करता है कि यह अनुमति दी जानी चाहिए। नोट, हालांकि, मानक में उदाहरण तकनीकी रूप से 'मानक' नहीं हैं (मानक में प्रस्ताव देखें); वे एक निश्चित बयान नहीं हैं कि क्या है और इसकी अनुमति नहीं है।

कहा कि, ज्यादातर लोगों समय के सबसे extern और एक प्रारंभकर्ता प्रयोग नहीं करते।

+0

मैं कोई प्रासंगिक उद्धरण या उदाहरण खोजने के लिए खंड 6.7.9 खोज रहा था। – haccks

6

इस कोड को पूरी तरह से वैध है।

लेकिन किसी भी संकलक अतिरिक्त (जानकारीपूर्ण या नहीं) निदान जारी करने के लिए नि: शुल्क है:

(C99, 5.1.1.3p1 fn 8) "बेशक, एक कार्यान्वयन के रूप में निदान के किसी भी संख्या का उत्पादन करने के लिए स्वतंत्र है एक वैध कार्यक्रम के रूप में अभी भी सही ढंग से अनुवाद किया गया है। "

कोई कंपाइलर क्या नहीं कर सकता है जब कोई बाधा या वाक्यविन्यास उल्लंघन होता है तो नैदानिक ​​उत्सर्जित नहीं होता है।

संपादित करें: ओपी प्रश्न टिप्पणी में डाल

devnull के रूप में, यूसुफ मायर्स से gcc टीम एक bug report पूछताछ इस निदान में बताते हैं:

"यह एक कोडन शैली चेतावनी है - कोड के बाद से "extern" आम तौर पर मतलब है कि घोषणा वस्तु की एक परिभाषा प्रदान नहीं कर रहा है उम्मीद है वैध, लेकिन बहुत unidiomatic सी के लिए है। "

+1

मुझे लगता है कि जीसीसी बग रिपोर्ट का सबसे प्रासंगिक हिस्सा यह है: "यह एक कोडिंग शैली चेतावनी है - कोड मान्य है, लेकिन" बाहरी "के बाद से सी के लिए अत्यंत unidiomatic आमतौर पर यह मतलब है कि घोषणा की परिभाषा नहीं दे रहा है उदेश्य।" –

+1

मैं इसे बग रिपोर्ट करने के लिए C99/C11 मानकों से उदाहरण (जो मैं अपने जवाब में उद्धृत) जोड़ने के लायक हो सकता है लगता है। –

+0

@ShafikYaghmour ने बग रिपोर्ट सामग्री के भाग को कवर करने के लिए एक संपादन जोड़ा – ouah

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