为什么外部链接到静态变量?

时间:2010-05-15 21:08:58

标签: c static extern

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

基本上,为什么文件范围中的int n与同一范围内的static int n不一样?它只与extern有关吗?如果是这样,我错过了extern呢?

4 个答案:

答案 0 :(得分:112)

static的全部和全部目的是声明变量对于在中声明的源文件是私有的。因此,它正在完成其防止外部连接的工作。

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

  1. int blah = 0; - blah在此文件中定义,可从其他文件访问。其他文件中的定义是重复的,会导致错误。
  2. extern int blah; - blah必须在别处定义,并从此文件中引用。
  3. int blah; - 这是FORTRAN COMMON的道德等同物。您可以在文件中包含任意数量的这些文件,链接器将它们全部解析为一个共享int。 (*)
  4. static int blah;(可选择使用初始化程序) - 这是静态的。这个文件完全是私有的。其他文件中的externs不可见,并且您可以拥有许多不同的文件,这些文件都声明为static TYPE blah;,并且它们都不同
  5. 对于观众中的纯粹主义者:'file'= 编译单元

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

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

答案 1 :(得分:6)

在标准C中,在函数外部声明的变量有两个范围。 static变量仅在声明它的编译单元(即文件)内可见,并且整个程序中可见非静态变量。 extern声明表示变量的位置尚未知晓,但将由链接器进行排序;它与非静态变量兼容,但extern static只是疯狂的谈话!

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

答案 2 :(得分:1)

根据MSDN文档:

  

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

http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx:2013年6月

答案 3 :(得分:1)

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

这就是我们尝试extern一个静态变量。声明extern static int i; - 类似于声明float int i; 你不能让float和int出现在同一个声明中吗?同样,您不能在同一声明中使用extern和static。