行为

2015-11-26 22 views
1

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”和“int i = 1”是i的有效定义,但实际上clang和gcc都不会为这种情况发出错误。任何人都可以解释细节吗?

+3

'int I;'是_declaration_和_ **暂定** definition_,而不是“normal”_definition_。 – Olaf

+0

闻起来像未定义的行为。 – Zimano

+0

这看起来很像描述而不是解释。如果我们删除尾部“int i = 1;” i的定义,每次对i的访问都可以看到编译器自动分配的值0。你能详细解释一下吗?谢谢〜 – bagwell

回答

1

这是试探性的定义,如解释here

在翻译单元的顶层(即预处理程序之后包含所有#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})实际的定义。

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

感谢您的链接! – bagwell