C编译器忽略结构声明的“静态”

时间:2018-08-29 22:41:19

标签: c struct static

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

static struct thing {
    int number;
};

并将其编译(在本例中为gcc),编译器将显示以下警告:

  

警告:此声明忽略了“静态”

     

[-Wmissing-declarations]

这是为什么?

我使结构静态的目的是将thing保留在全局名称空间之外,以便另一个文件可以声明自己的thing

3 个答案:

答案 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 ++中的规则非常不同。)