C 头文件中未初始化全局变量的行为

C 头文件中未初始化全局变量的行为,c,C,测试.h #ifndef TEST_H #define TEST_H int i; int i = 1; // why no redefinition error issued? #endif /* TEST_H */ test.c #include "test.h" int main() { int x; int x = i; // obviously, a redefinition return 0; } 我真的很好奇头文件中未初始化的全局变量的行为。据我所知,“i

测试.h

#ifndef TEST_H
#define TEST_H

int i;

int i = 1; // why no redefinition error issued?

#endif  /* TEST_H */
test.c

#include "test.h"

int main() {
  int x;
  int x = i; // obviously, a redefinition
  return 0;
}

我真的很好奇头文件中未初始化的全局变量的行为。据我所知,“inti;”和“inti=1”都是I的有效定义,但在实践中,clang和gcc都不会对这种情况发出错误。有人能解释一下细节吗?

这是一个初步的定义

在翻译单元的顶层(即预处理器后包含所有#include的源文件),每个C程序都是一系列声明,它们声明具有外部链接的函数和对象。这些声明称为外部声明,因为它们出现在任何函数之外

暂定定义

暂定定义是没有初始值设定项、没有存储类说明符或带有静态说明符的外部声明

暂定定义是一种声明,可以作为定义,也可以不作为定义。如果在同一翻译单元中更早或更晚找到实际的外部定义,那么暂定定义只是作为声明

int i1 = 1;     // definition, external linkage
int i1;         // tentative definition, acts as declaration because i1 is defined
extern int i1;  // declaration, refers to the earlier definition

extern int i2 = 3; // definition, external linkage
int i2;            // tentative definition, acts as declaration because i2 is defined
extern int i2;     // declaration, refers to the external linkage definition
如果在同一翻译单元中没有定义,则暂定定义将充当初始值设定项
=0
(或者,对于数组类型,
={0}
)的实际定义


inti是一个声明和暂定定义,而不是“正常”定义。闻起来像是未定义的行为。这看起来像是一种描述,而不是解释。如果我们删除i后面的“inti=1;”定义,那么对i的每个后续访问都可以看到一个值0,该值由编译器自动赋值。你能再详细解释一下吗?谢谢~谢谢你的链接!
int i3;        // tentative definition, external linkage
int i3;        // tentative definition, external linkage
extern int i3; // declaration, external linkage
// in this translation unit, i3 is defined as if by "int i3 = 0;"