变量的外部和静态链接的奇怪行为
Weird behavior with extern and static linkage of variables
我发现 extern
和 static
(内部)变量的某些行为很奇怪。
这是一个例子:
/* file a.c */
#include <stdio.h>
/* variable with static linkage */
static int x = 24;
int f() {
/* variable with extern linkage */
extern int x;
return x;
}
int main() {
printf("%d\n", f());
return 0;
}
-
/* file x.c */
/* define symbol `x` to be an `int` equal to 100 */
int x = 100;
我编译这个程序使用:
$ cc a.c x.c -o a
然后我 运行 我的程序得到这个输出:
$ ./a
24
为什么这个程序输出 24
而不是 100
?
引用自link
The following table identifies the linkage assigned to an object that is declared twice in a single translation unit. The column designates the first declaration, and the row designates the redeclaration.
同样来自标准第 6.2.2 节:
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
因此文件 a.c
的所有外部链接都已在内部解析。
您的代码首先将 x
定义为静态,然后在翻译单元 a.c 中将其定义为外部。因此,链接是来自上面 table 的内部链接。所以它打印 24
.
我发现 extern
和 static
(内部)变量的某些行为很奇怪。
这是一个例子:
/* file a.c */
#include <stdio.h>
/* variable with static linkage */
static int x = 24;
int f() {
/* variable with extern linkage */
extern int x;
return x;
}
int main() {
printf("%d\n", f());
return 0;
}
-
/* file x.c */
/* define symbol `x` to be an `int` equal to 100 */
int x = 100;
我编译这个程序使用:
$ cc a.c x.c -o a
然后我 运行 我的程序得到这个输出:
$ ./a
24
为什么这个程序输出 24
而不是 100
?
引用自link
The following table identifies the linkage assigned to an object that is declared twice in a single translation unit. The column designates the first declaration, and the row designates the redeclaration.
同样来自标准第 6.2.2 节:
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
因此文件 a.c
的所有外部链接都已在内部解析。
您的代码首先将 x
定义为静态,然后在翻译单元 a.c 中将其定义为外部。因此,链接是来自上面 table 的内部链接。所以它打印 24
.