2012-01-26 112 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

没有任何奇怪的扩展。它必须是这个编译器的东西。感谢您的意见,我很感激。 –

相关问题