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

时间:2015-11-26 18:17:33

标签: c

test.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;
}

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

1 个答案:

答案 0 :(得分:1)

这是here解释的暂定定义。

在翻译单元的顶层(即,在预处理器之后具有所有#includes的源文件),每个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})。

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;"