63

为什么extern int n在声明 n 时(在不同的文件中)不编译static int n,但在声明时工作int n?(这两个声明都在文件范围内。)

基本上,为什么int n在文件范围内与static int n在同一范围内不一样?它仅与外部有关吗?如果是这样,我错过了 extern 怎么办?

4

4 回答 4

138

的全部和全部目的static是声明一个变量对于它在 中声明的源文件是私有的。因此,它在防止来自外部的连接方面做得恰到好处。

请记住,文件范围变量定义有四种风格:

  1. int blah = 0;— blah 在此文件中定义并可从其他文件访问。其他文件中的定义是重复的,会导致错误。
  2. extern int blah;— blah 必须在别处定义并从此文件中引用。
  3. int blah;— 这是 FORTRAN 的道德等价物COMMON。您可以在文件中包含任意数量的这些,并且它们都由链接器解析为一个 shared int。(*)
  4. static int blah;(可选地使用初始化器)——这是静态的。它对该文件是完全私有的。它对其他文件中的外部人员不可见,并且您可以有许多不同的文件都声明static TYPE blah;,并且它们都是不同的。

对于听众中的纯粹主义者:'file' =编译单元

请注意,静态内部函数(不在文件范围内)的范围更窄:如果两个函数static int bleh = 0;即使在同一个文件中声明,它们也是不相关的。

(*):对于那些不熟悉的人:在通常的模式中,一个编译单元必须定义一个全局变量,其他编译单元可以引用它。它“生活”在那个编译单元中。在上述情况 (3) 中,没有文件(或所有文件)定义它。如果两个文件都说int blah = 0;,链接器将抱怨多个定义。如果两个文件说int blah;链接器很高兴地创建了一个全局int并导致所有代码都引用它。

于 2010-05-15T21:10:34.750 回答
7

在标准 C 中,在函数外部声明的变量有两个作用域。变量仅在static声明它的编译单元(即文件)内可见,非静态变量在整个程序中可见。声明说变量的extern位置尚不清楚,但将由链接器排序;它与非静态变量兼容,但extern static只是疯狂的谈话!

当然,在实践中,这些天还有其他可见性。特别是,现在在单个源文件和整个程序之间存在范围级别;单个共享库的级别是有用的(可通过 GCC 函数属性等机制设置)。但这只是非静态变量主题的一种变体;static保持与以前相同的解释。

于 2010-05-15T21:21:18.417 回答
2

根据 MSDN 文档:

修改变量时,static关键字指定变量具有静态持续时间(程序开始时分配,程序结束时释放)并将其初始化为0,除非指定另一个值。在文件范围内修改变量或函数时,static 关键字指定变量或函数具有内部链接(其名称在声明它的文件之外不可见)。

MSDN 上的静态 (C++):存档于 2015 年 1 月;另请参阅最新文档:静态§ 存储类 (C++) | 微软文档

于 2013-06-25T21:44:02.323 回答
1

iv.c:2:1:错误:声明说明符 extern static int i 中有多个存储类;^

这就是我们尝试外部静态变量的结果。声明 extern static int i; - 类似于声明 float int i;你不能让 float 和 int 出现在同一个声明中,对吧?同样,您不能在同一个声明中包含 extern 和 static。

于 2015-12-17T04:41:51.240 回答