我很困惑为什么以下工作:
测试.c
#include <stdio.h>
int g;
// ??? should be extern int g; ???
int main(){
printf("%in", g);
return 0;
}
lib.c
int g = 3;
为什么我在编译时没有收到重复符号错误?我在尝试C++执行此操作时收到错误,因此这让我满意。但是,在这个例子中,无论我是否包含extern,一切都可以编译和工作(即成功打印3)。通过阅读 StackOverflow 上关于 C 语言中 extern 的所有其他问题,每个人似乎都在说变量上使用的 extern 声明了变量,但没有为其定义(即分配内存)。但是在这里,如果我不使用extern,那么我正在定义两个单独的变量,都称为g,所以应该有某种重复的符号错误。但是没有,所以我很困惑。
N1570, 6.9.2 (强调我的):
2 具有文件作用域的对象的标识符声明 没有初始值设定项,也没有存储类说明符或 存储类说明符 static,构成暂定 定义。
4 示例 1
int i1 = 1; // definition, external linkage static int i2 = 2; // definition, internal linkage extern int i3 = 3; // definition, external linkage int i4; // tentative definition, external linkage static int i5; // tentative definition, internal linkage int i1; // valid tentative definition, refers to previous int i2; // 6.2.2 renders undefined, linkage disagreement int i3; // valid tentative definition, refers to previous int i4; // valid tentative definition, refers to previous int i5; // 6.2.2 renders undefined, linkage disagreement extern int i1; // refers to previous, whose linkage is external extern int i2; // refers to previous, whose linkage is internal extern int i3; // refers to previous, whose linkage is external extern int i4; // refers to previous, whose linkage is external extern int i5; // refers to previous, whose linkage is internal
"test.c"中的int g;
是一个暂定定义,给出了g
外部链接(参见示例)。但是,"lib.c"中的int g = 3;
有一个初始化器,所以它不是一个暂定的定义。因此,"test.c"中的g
引用了"lib.c"中的g
,其值初始化为3。
另请参阅:http://en.cppreference.com/w/c/language/extern