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

标签 c

测试.h

#ifndef TEST_H
#define TEST_H

int i;

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

#endif  /* TEST_H */

测试.c

#include "test.h"

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

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

最佳答案

解释为暂定定义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;"

关于c - 头文件中未初始化的全局变量的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33944923/

相关文章:

c - C 中奇怪的指针行为

c - 将结构体数组作为参数传递给函数

c++ - 使用 C isdigit 进行错误检查

c - 使用 C 编程的 Linux 管道。通过管道重定向输入/输出

c - 在C中传递Void类型参数

c - C中奇怪的变量参数问题

c - 如何使用 FILE 结构的成员打印文件中的第一个字符?

c - 如何在迷宫中打印从源到目标的 BFS 路径

到另一台服务器中的远程 DB2 数据库的连接字符串

c - 如何在没有 eof 的情况下 recv 直到没有更多的 recv?