在 C 中省略变量的 extern,但仍然有效?
omission of extern for variable in C, but still works?
我很困惑为什么会出现以下问题:
test.c
#include <stdio.h>
int g;
// ??? should be extern int g; ???
int main(){
printf("%i\n", g);
return 0;
}
lib.c
int g = 3;
为什么我在编译时没有收到重复符号错误?我在 C++ 中尝试执行此操作时遇到错误,这让我很满意。然而,在这个例子中,无论我是否包含 extern,一切都会编译和工作(即成功打印 3)。通过阅读 Whosebug 上关于 C 中的 extern 的所有其他问题,每个人似乎都在说用于变量的 extern 声明变量但不为其定义(即分配内存)。但是在这里,如果我不使用 extern,那么我定义了两个单独的变量,都称为 g,因此应该存在某种重复符号错误。但是没有,所以很迷茫
N1570, 6.9.2(强调我的):
2 A declaration of an identifier for an object that has file scope
without an initializer, and without a storage-class specifier or with
the storage-class specifier static, constitutes a tentative
definition.
4 EXAMPLE 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。
我很困惑为什么会出现以下问题:
test.c
#include <stdio.h>
int g;
// ??? should be extern int g; ???
int main(){
printf("%i\n", g);
return 0;
}
lib.c
int g = 3;
为什么我在编译时没有收到重复符号错误?我在 C++ 中尝试执行此操作时遇到错误,这让我很满意。然而,在这个例子中,无论我是否包含 extern,一切都会编译和工作(即成功打印 3)。通过阅读 Whosebug 上关于 C 中的 extern 的所有其他问题,每个人似乎都在说用于变量的 extern 声明变量但不为其定义(即分配内存)。但是在这里,如果我不使用 extern,那么我定义了两个单独的变量,都称为 g,因此应该存在某种重复符号错误。但是没有,所以很迷茫
N1570, 6.9.2(强调我的):
2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.
4 EXAMPLE 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。