2014-06-26 101 views
12

Wiki說:如何定義extern變量和聲明?

extern關鍵詞的意思是 「無申報確定」。換句話說,它是一種顯式聲明變量的方法,或者在沒有定義的情況下強制聲明。 也可以明確定義變量,即強制定義。這是通過將一個初始化值分配給一個變量完成的。

這意味着,一個extern聲明初始化變量作爲該變量的定義。所以,

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

應該是有效的(compiled in C++11)。但是,當選擇-Wall -Wextra -pedantic -std=c99在GCC 4.7.2編譯,生成警告:

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

這不應該。據我所知,

extern int y = 0; 

實際上是相同的

int i = 0; 

什麼錯嗎?

+3

[This](http://stackoverflow.com/questions/4268589/warning-in-extern-declaration)也可能有所幫助。不是被接受的答案,而是[AndreyT]提供的答案(http://stackoverflow.com/users/187690/andreyt)。特別注意答案的最後一行:_Just在編譯器設置中禁用這個警告(並且,請寫一封關於GCC團隊的粗魯的信件)._ – devnull

+0

@devnull;是的.. – haccks

+0

@devnull;人。你救了我。我一個小時左右就搞亂了!非常感謝:) – haccks

回答

5

標準的三個版本 - ISO/IEC 9899:1990,ISO/IEC 9899:1999和ISO/IEC 9899:2011 - 包含在標題部分爲例外部對象定義(§ C90的6.7.2和§6.9。C99和C11),其示出的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放在OP問題的意見,約瑟夫·邁爾斯從gcc團隊在bug report質疑該診斷說明:

「這是一種編碼風格警告 - 該代碼是有效的,但是對於C來說,單向性是極其有效的,因爲「extern」通常意味着 聲明不提供該對象的定義。「

+1

我認爲GCC錯誤報告中最相關的部分是:「這是一種編碼風格警告 - 代碼是有效的,但對C來說非常單一,因爲」extern「通常預期意味着該聲明沒有提供物體。」 –

+1

我認爲可能值得將C99/C11標準中的例子(我在我的回答中引用)添加到錯誤報告中。 –

+0

@ShafikYaghmour添加了一個編輯來覆蓋部分錯誤報告內容 – ouah