C编译器忽略’static’来声明struct

C compiler ignores 'static' for declaration of struct

在C语言中,如果我声明这样的结构:

1
2
3
static struct thing {
    int number;
};

并编译它(在本例中使用gcc),编译器将打印此警告:

warning: 'static' ignored on this declaration

[-Wmissing-declarations]

为什么会这样?

我的目的是使结构保持静态,以便另一个文件可以声明自己的thing,如果需要的话。


如果不定义实际对象,则无法定义存储。

1
2
3
static struct thing {
    int number;
}obj1,obj2;

可以,而且:

1
2
3
4
5
struct thing {
    int number;
};

static struct thing x,y;

结构标记(和typedef名称)没有链接,这意味着它们不在翻译单元之间共享。您可以使用术语"private"来描述这一点。两个不同的单位定义自己的struct thing是完全可以的。

只有当它试图对具有外部链接的函数进行跨单元调用,而外部链接接受从该函数派生的struct thing或类型时,才会出现问题。通过确保只有通过头文件中的原型(即不要使用本地原型)调用具有外部链接的函数,可以将发生这种情况的可能性降到最低。


在这种方式下,不能像对函数或对象那样使用static来控制类型的链接,因为在C类型中,无论如何都没有链接。

"全局命名空间"不是您想要的术语。c将对象和函数的名称描述为具有"外部链接"(如果相同的名称可以在不同的翻译单元中声明为表示相同的内容(如函数的默认值),"内部链接"(如果相同的名称可以在相同的翻译单元中重新声明为表示相同的内容(如标记为static的声明),或)当一个声明与任何其他声明(如在函数体中定义的变量)命名不同的对象或函数时,没有链接。(大致来说,翻译单元是一个*.c文件及其包含的头文件的内容。)但这些都不适用于类型。

所以,如果您想要使用一个对一个源文件本质上是私有的结构类型,只需在那个源文件中定义它。然后,您不必担心相同名称的另一个用法会与您的名称冲突,除非可能有人将其添加到源文件包含的头文件中。

(而且,如果C++用户遇到这个问答,请注意C++中的规则非常不同。)