关于C#:为什么extern链接到静态变量?

Why won't extern link to a static variable?

当声明n(在另一个文件中)static int n时,为什么extern int n不编译,而声明int n时,它工作?(这两个声明都在文件范围内。)

基本上,为什么文件范围中的int n与同一范围中的static int n不同?它只与外部有关吗?如果是这样的话,那我是不是失踪了?


static的全部和全部目的是声明一个变量对于声明它的源文件是私有的。因此,它在防止外部连接方面做得很精确。

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

  • int blah = 0;blah在此文件中定义,可从其他文件访问。其他文件中的定义是重复的,会导致错误。
  • extern int blah;blah必须在其他地方定义,并从该文件引用。
  • int blah;—这是Fortran COMMON的道德等价物。文件中可以有任意数量的这些文件,它们都由链接器解析为一个共享的int。(*)
  • static int blah;(可选带初始值设定项)-这是静态的。它完全是这个文件的私有。它在其他文件中是不可见的,您可以有许多不同的文件,它们都声明static TYPE blah;,并且它们都是不同的。
  • 对于听众中的纯粹主义者:"文件"=编译单元。

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

    (*):对于不熟悉的人:在通常的模式中,一个编译单元必须定义一个全局变量,而其他的则可以引用它。它"活"在那个编译单元中。在上述情况(3)中,没有文件(或所有文件)定义它。如果有两个文件称为int blah = 0;,那么链接器将投诉多个定义。如果两个文件说是int blah;,那么链接器会愉快地创建一个全局int,并使所有代码引用它。


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

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


    IV.C:2:1:错误:声明说明符中有多个存储类外部静态I;^

    这就是我们试图消除静态变量时得到的结果。声明extern static int i;—类似于声明float int i;不能让float和in t出现在同一声明中,对吗?同样,在同一声明中不能有extern和static。


    根据MSDN文档:

    When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).

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