2012-01-26 113 views
5

我今天碰到一些令我感到意外的代碼。在.c文件中定義了一個變量(在函數之外)是靜態的。但是,在.h文件中它被聲明爲extern。下面是代碼的一個類似的例子:當變量定義爲靜態但聲明爲extern時,沒有警告或錯誤指示

結構定義和申報.H:

typedef struct 
{ 
    unsigned char counter; 
    unsigned char some_num; 
} One_Struct; 

typedef struct 
{ 
    unsigned char counter; 
    unsigned char some_num; 
    const unsigned char * p_something; 
} Another_Struct; 

typedef struct 
{ 
    One_Struct * const p_one_struct; 
    Another_Struct * const p_another_struct; 
} One_Useful_Struct; 

extern One_Useful_Struct * const p_my_useful_struct[]; 

定義和初始化以.c:

static One_Useful_Struct * const p_my_useful_struct[MAX_USEFUL_STRUCTS] = 
{ 
    &p_my_useful_struct_regarding_x, 
    &p_my_useful_struct_regarding_y, 
}; 

問題: 所以我的問題是,爲什麼我沒有收到編譯器錯誤或警告?

這段代碼現在已經在其他項目中成功運行了一段時間了。我確實注意到,指針不會在定義它的.c文件之外使用,並且被正確定義爲靜態(我刪除了外部聲明)。我發現它的唯一原因是因爲我在這個項目上跑了Lint,而Lint把它拿起來了。

回答

6

這certianly也不是標準C. GCC和鐺同時檢測到,並就這種情況下的錯誤:

$ gcc example.c 
example.c:4: error: static declaration of ‘x’ follows non-static declaration 
example.c:3: error: previous declaration of ‘x’ was here 
$ clang example.c 
example.c:4:12: error: static declaration of 'x' follows non-static declaration 
static int x; 
     ^
example.c:3:12: note: previous definition is here 
extern int x; 
     ^
1 error generated. 

您必須使用一個相當寬容的編譯器 - 也許Visual Studio的?我剛剛檢查了我的Windows機器,並且VS2003默默接受了我的示例程序。添加/Wall並給予警告:

> cl /nologo /Wall example.c 
example.c 
example.c(4) : warning C4211: nonstandard extension used : redefined extern to static 

就像你使用任何編譯器的擴展它是你使用我看來。

+0

這是一個很好的觀點,我將不得不考慮哪些擴展是到位的。我正在使用Keil uVision for ARM。 –

+0

沒有任何奇怪的擴展。它必須是這個編譯器的東西。感謝您的意見,我很感激。 –

相關問題