当变量定义为static但声明为extern时,没有警告或错误指示



我今天遇到了一些让我惊讶的代码。在.c文件中,一个变量(在函数之外)被定义为静态。但是,在.h文件中,它被声明为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把它捡了起来。

这肯定不是标准的C.GCC和clang都检测到并给出了这种情况下的错误:

$ 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

在我看来,你使用的是任何编译器的扩展。

最新更新