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

时间:2012-01-26 01:12:50

标签: c

我今天遇到了一些让我感到惊讶的代码。变量在.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选择了它。

1 个答案:

答案 0 :(得分:6)

它通常不是标准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

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