为什么extern int n
在声明 n 时(在不同的文件中)不编译static int n
,但在声明时工作int n
?(这两个声明都在文件范围内。)
基本上,为什么int n
在文件范围内与static int n
在同一范围内不一样?它仅与外部有关吗?如果是这样,我错过了 extern 怎么办?
的全部和全部目的static
是声明一个变量对于它在 中声明的源文件是私有的。因此,它在防止来自外部的连接方面做得恰到好处。
请记住,文件范围变量定义有四种风格:
int blah = 0;
— blah 在此文件中定义并可从其他文件访问。其他文件中的定义是重复的,会导致错误。extern int blah;
— blah 必须在别处定义并从此文件中引用。int blah;
— 这是 FORTRAN 的道德等价物COMMON
。您可以在文件中包含任意数量的这些,并且它们都由链接器解析为一个 shared int
。(*)static int blah;
(可选地使用初始化器)——这是静态的。它对该文件是完全私有的。它对其他文件中的外部人员不可见,并且您可以有许多不同的文件都声明static TYPE blah;
,并且它们都是不同的。对于听众中的纯粹主义者:'file' =编译单元。
请注意,静态内部函数(不在文件范围内)的范围更窄:如果两个函数static int bleh = 0;
即使在同一个文件中声明,它们也是不相关的。
(*):对于那些不熟悉的人:在通常的模式中,一个编译单元必须定义一个全局变量,其他编译单元可以引用它。它“生活”在那个编译单元中。在上述情况 (3) 中,没有文件(或所有文件)定义它。如果两个文件都说int blah = 0;
,链接器将抱怨多个定义。如果两个文件说int blah;
链接器很高兴地创建了一个全局int
并导致所有代码都引用它。
在标准 C 中,在函数外部声明的变量有两个作用域。变量仅在static
声明它的编译单元(即文件)内可见,非静态变量在整个程序中可见。声明说变量的extern
位置尚不清楚,但将由链接器排序;它与非静态变量兼容,但extern static
只是疯狂的谈话!
当然,在实践中,这些天还有其他可见性。特别是,现在在单个源文件和整个程序之间存在范围级别;单个共享库的级别是有用的(可通过 GCC 函数属性等机制设置)。但这只是非静态变量主题的一种变体;static
保持与以前相同的解释。
根据 MSDN 文档:
修改变量时,static关键字指定变量具有静态持续时间(程序开始时分配,程序结束时释放)并将其初始化为0,除非指定另一个值。在文件范围内修改变量或函数时,static 关键字指定变量或函数具有内部链接(其名称在声明它的文件之外不可见)。
MSDN 上的静态 (C++):存档于 2015 年 1 月;另请参阅最新文档:静态§ 存储类 (C++) | 微软文档
iv.c:2:1:错误:声明说明符 extern static int i 中有多个存储类;^
这就是我们尝试外部静态变量的结果。声明 extern static int i; - 类似于声明 float int i;你不能让 float 和 int 出现在同一个声明中,对吧?同样,您不能在同一个声明中包含 extern 和 static。