【问题标题】:Behavior of an uninitialized global variable in a header file头文件中未初始化的全局变量的行为
【发布时间】:2016-02-29 22:05:15
【问题描述】:

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 都不会针对这种情况发出错误。谁能详细解释一下?

【问题讨论】:

  • int I;声明暂定定义,而不是“正常”定义.
  • 闻起来像未定义的行为。
  • 这看起来像是一种描述而不是解释。如果我们删除尾随的“int i = 1;” i 的定义,每次对 i 的访问都可以看到由编译器自动分配的值 0。你能进一步详细解释一下吗?谢谢~

标签: c


【解决方案1】:

这是暂定定义,如here 所述。

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

暂定定义

暂定定义是没有初始化器的外部声明,或者没有存储类说明符或带有说明符 static。

暂定定义是一个声明,可能会或可能不会作为定义。如果在同一个翻译单元中更早或更晚地找到了实际的外部定义,则暂定定义仅充当声明。

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

【讨论】:

  • 感谢您的链接!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多