在C语言中,如果我声明这样的结构:
static struct thing {
int number;
};
并将其编译(在本例中为gcc),编译器将显示以下警告:
警告:此声明忽略了“静态”
[-Wmissing-declarations]
这是为什么?
我使结构静态的目的是将thing
保留在全局名称空间之外,以便另一个文件可以声明自己的thing
。
答案 0 :(得分:5)
您不能在没有定义实际对象的情况下定义存储。
static struct thing {
int number;
}obj1,obj2;
还可以,
struct thing {
int number;
};
static struct thing x,y;
答案 1 :(得分:4)
结构标签(和typedef名称)没有链接,这意味着它们不会在翻译单元之间共享。您可以使用术语“专用”来描述这一点。两个不同的单位定义自己的struct thing
很好。
只有尝试使用具有外部链接的函数来跨单元调用该函数,该外部链接接受struct thing
或从中派生的类型。通过确保仅通过头文件中的原型调用具有外部链接的函数(即,不要使用本地原型),可以将发生这种情况的可能性降到最低。
答案 2 :(得分:1)
您不能以这种方式使用static
来控制类型的链接,就像您对函数或对象的控制一样,因为在C语言中,类型永远都没有链接。
“全局名称空间”并不是您想要的术语。如果可以在不同的翻译单元中声明相同的名称来表示相同的事物(如函数的默认值),则C将对象和函数的名称描述为具有“外部链接”,如果可以在内部重新声明相同的名称,则将“内部链接”描述为具有“外部链接”。相同的翻译单元表示相同的内容(例如标记为static
的声明),或者当声明与其他任何声明(例如函数体内定义的变量)命名不同的对象或函数时,则为“无链接”。 (大致来说,翻译单元是一个* .c文件,包括它的标头内容。)但这都不适用于类型。
因此,如果要使用本质上对一个源文件专用的结构类型,只需在该源文件中定义它即可。然后,您不必担心同名的其他用法会与您的名冲突,除非有人将其添加到源文件包含的头文件中。
(以防万一C ++用户遇到此问题,请注意,C ++中的规则非常不同。)