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

emb*_*guy 5 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[];
Run Code Online (Sandbox Code Playgroud)

.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,
};
Run Code Online (Sandbox Code Playgroud)

问: 所以我的问题是,为什么我没有收到编译器错误或警告?

代码已经在其他项目中成功运行了一段时间.我注意到指针永远不会在定义它的.c文件之外使用,并且被正确定义为静态(我删除了外部声明).我找到它的唯一原因是因为我在项目上运行了Lint并且Lint选择了它.

Car*_*rum 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.
Run Code Online (Sandbox Code Playgroud)

您必须使用非常宽松的编译器 - 也许是Visual Studio?我刚刚检查了我的Windows机器,VS2003默默地接受了我的示例程序.添加/Wall会发出警告:

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

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