C语言 为什么不外部链接到静态变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2841762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why won't extern link to a static variable?
提问by Jared Pochtar
Why does extern int nnot compile when n is declared (in a different file) static int n, but works when declared int n? (Both of these declarations were at file scope.)
为什么extern int n在声明 n 时不编译(在不同的文件中)static int n,但在声明时有效int n?(这两个声明都在文件范围内。)
Basically, why is int nin file scope not the same as static int nin the same scope? Is it only in relation to extern? If so, what about extern am I missing?
基本上,为什么int n在文件范围内与static int n在同一范围内不同?它仅与外部有关吗?如果是这样,我想念 extern 吗?
回答by bmargulies
The whole and entire purpose of staticis to declare that a variable is private to the source file that it is declared in. Thus, it is doing precisely its job in preventing a connection from an extern.
的全部和全部目的static是声明一个变量对于它在 中声明的源文件是私有的。因此,它在防止来自外部的连接方面做得恰到好处。
Keep in mind that there are four flavors of file-scope variable definition:
请记住,文件范围变量定义有四种风格:
int blah = 0;— blah is defined in this file and accessible from other files. Definitions in other files are duplicates and will lead to errors.extern int blah;— blah must be defined elsewhere and is referenced from this file.int blah;— This is the moral equivalent of FORTRANCOMMON. You can have any number of these in files, and they are all resolved by the linker to one sharedint. (*)static int blah;(optionally with an initializer) — This is static. It is completely private to this file. It is not visible to externs in other files, and you can have many different files that all declarestatic TYPE blah;, and they are all different.
int blah = 0;— blah 在此文件中定义,可从其他文件访问。其他文件中的定义是重复的,会导致错误。extern int blah;— blah 必须在别处定义并从此文件中引用。int blah;— 这是 FORTRAN 的道德等价物COMMON。您可以在文件中包含任意数量的这些,并且它们都由链接器解析为一个共享的int. (*)static int blah;(可选地带有初始化程序)——这是静态的。这个文件是完全私有的。这是不是在其他文件实习医生可见,你可以有许多不同的文件,所有的声明static TYPE blah;,而且都是不同的。
For the purists in the audience: 'file' = compilation unit.
对于观众中的纯粹主义者:“文件”=编译单元。
Note that static inside functions (not at file scope) are even more tightly scoped: if two functions declare static int bleh = 0;even in the same file, they are unrelated.
请注意,静态内部函数(不在文件范围内)的范围更加严格:如果两个函数static int bleh = 0;甚至在同一个文件中声明,则它们是不相关的。
(*): for those of you not familiar: in the usual pattern, one compilation unit has to define a global variable, and others can reference it. It 'lives' in that compilation unit. In case (3), above, no file (or all the files) defines it. If two files say int blah = 0;, the linker will complain of multiple definitions. If two files say int blah;the linker cheerfully creates a single global intand causes all the code to refer to it.
(*):对于那些不熟悉的人:在通常的模式中,一个编译单元必须定义一个全局变量,其他人可以引用它。它“存在”在那个编译单元中。在上面的情况 (3) 中,没有文件(或所有文件)定义它。如果两个文件说int blah = 0;,链接器将抱怨多个定义。如果两个文件说int blah;链接器愉快地创建了一个全局变量int并导致所有代码都引用它。
回答by Donal Fellows
In standard C, there are two scopes for variables declared outside of a function. A staticvariable is only visible inside the compilation unit (i.e., file) that declared it, and non-static variables are visible across the whole program. An externdeclaration says that the variable's location isn't known yet, but will be sorted out by the linker; it's compatible with non-static variables, but extern staticis just crazy talk!
在标准 C 中,在函数外部声明的变量有两个作用域。一个static变量仅仅是宣布它的编译单元(即文件)中可见,和非静态变量在整个程序中可见。的extern声明说,该变量的位置尚不清楚,但会通过链接进行清理整顿; 它与非静态变量兼容,但extern static只是胡说八道!
Of course, in practice there are other visibilities these days. In particular, there are now scoping levels between that of a single source file and a whole program; the level of a single shared library is a useful one (settable through mechanisms like GCC function attributes). But that's just a variation on the theme of non-static variables; statickeeps the same interpretation it had before.
当然,在实践中,这些天还有其他可见性。特别是,现在在单个源文件和整个程序之间存在范围级别;单个共享库的级别是有用的(可通过 GCC 函数属性等机制设置)。但这只是非静态变量主题的一个变体;static保持与之前相同的解释。
回答by felknight
According to MSDN documentation:
根据 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).
修改变量时,static 关键字指定变量具有静态持续时间(在程序开始时分配并在程序结束时释放)并将其初始化为 0,除非指定了另一个值。在文件范围内修改变量或函数时,static 关键字指定变量或函数具有内部链接(其名称在声明它的文件外部不可见)。
http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx: June 2013
http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx:2013 年6 月
回答by Gautham
iv.c:2:1: error: multiple storage classes in declaration specifiers extern static int i; ^
iv.c:2:1: 错误:声明说明符中的多个存储类 extern static int i;^
That is what we get on attempting to extern a static variable. Declaring extern static int i; - is analogous to the declaration float int i; You can't have float and int appear in the same declaration right? Similarly, you can't have extern and static in the same declaration.
这就是我们尝试外部静态变量所得到的结果。声明 extern static int i; - 类似于声明 float int i; 你不能让 float 和 int 出现在同一个声明中吗?同样,您不能在同一个声明中使用 extern 和 static。

