C 中的 extern 声明和定义
据我所知,C中的全局变量可以是一到两个不同的存储类,并且声明可以用两个不同的关键字给出,相应地,
extern int foo; //default
static int bar;
静态变量仅在声明的模块内可见,并且不能导出。在 extern 声明的情况下,变量位于链接的所有模块的公共命名空间中,除非被静态变量遮蔽。
虽然静态变量必须在其模块中定义,但外部变量可以在其他地方定义。如果曾经使用过它,则必须对其进行定义。
我的编译器(GCC)接受
static int bar = 5;
但抛出一个抱怨
extern int foo = 4;
似乎预期外部变量永远不会用关键字“extern”定义。这就引出了以下问题:
上例中的对象“foo”在定义它的模块中具有什么类型的存储类?
a global variable may one to two different storage classes in C, to my best knowledge, and the declaration may be given with two different keywords, correspodingly
extern int foo; //default
static int bar;
Static variables are only visible within the module of declaration, and cannot be exported. In case of extern declaration, the variable is in the common namespace of all modules linked, unless shadowed by static variable.
Whereas static variables have to be defined in their module, an extern variable may be defined somewhere else. It has to be defined if ever used.
My compiler (GCC) accepts
static int bar = 5;
but casts a complain at
extern int foo = 4;
It seems to be expected that extern variables are never defined with the keyword 'extern'. This leads to the following question:
What kind of storage class does the Object 'foo' in the example above have in the module where it is defined?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
IIRC,
extern
更多的是向编译器暗示它不必为该值分配存储空间。链接器预计会在另一个编译单元中找到该值。通常,extern
用于头文件中,以指示某人已定义与该名称关联的存储。该值的定义不包含 extern 关键字,因为编译器必须在包含该定义的编译单元中为该值分配存储空间。有关更多详细信息,请参阅外部存储类说明符。
IIRC,
extern
is more of a hint to the compiler that it does not have to allocate storage for the value. The linker is expected to find the value in another compilation unit. Usuallyextern
is used in header files to indicate that the someone has defined storage associated with the name. The definition of the value does not include theextern
keyword since the compiler has to allocate storage for the value in the compilation unit that includes the definition.See extern storage class specifier for more details.
extern 变量将在定义它的单元中使用全局范围(导出)进行定义:
int baz = 5;
The extern variable will be defined with a global scope (exported) in the unit where it is defined:
int baz = 5;
默认存储类别为
auto
。The default storage class is
auto
.实际上你错过了两个存储类:auto 和 register
注册在这里并不重要,但默认存储类别是auto。
自动为内存中某处的变量保留空间(这通常是您声明变量时想要的)。应该注意的是,对于“自动变量”,每次进入变量的范围时都会分配新的空间。 (即,当 func() 声明“auto”变量时,从 func() 内调用函数 func() 将产生两个不同的变量,并且每次调用 func() 只会知道其自己的变量。
由此可见,在全局范围内声明的自动变量将是唯一的(因为该范围仅输入一次)。
然而,静态变量始终是唯一的。独特之处在于空间只会被分配一次。当 func() 调用 func() 并且您希望两个函数调用都对同一变量进行操作时,这非常有用。
外部变量只是对唯一变量的引用。
当您想要访问在不同文件中声明的全局变量时,可以使用它们。
鉴于文件 1.c 和 2.c,声明“int global;”是不够的。在这两个文件中,因为空间将被分配两次并且名称冲突将导致链接错误。
因此,您要做的就是在一个文件中保留空间(使用“int global;”),并在另一个文件中告诉链接器通过编写“extern int global;”在另一个文件中查找名称为“global”的变量。
Actually you missed two storage classes: auto and register
Register doesn't matter here but the default storage class is auto.
Auto reserves space for a variable somewhere in the memory (which is usually what you want when you declare a variable). It should be noted that for 'auto variables' new space will be allocated every time the scope of the variable is entered. (i.e. calling the function func() from within func() when func() declares an 'auto' variable will result in two different variables and each call to func() will only know about its own variable.
From this follows that auto variables declared at the global scope will be unique (since the scope is enterd only once).
Static variables however are always unique. Unique in the sense that space will only be allocated once. This is useful when func() calls func() and you want both function calls to operate on the same variable.
Extern variables are simply references to unique variables.
You use these when you want to access a global variable declared in a different file.
Given the files 1.c and 2.c it does not suffice to declare "int global;" in both files because space would be allocated twice and the name clash would result in a linking error.
Hence what you do is in one file to reserve space (using "int global;") and in the other file tell the linker to look for a variable of the name "global" in another file by writing "extern int global;".