首页 > 解决方案 > C 头文件中的全局变量初始化

问题描述

我想知道为什么在 C 中的多个源中包含的头文件中声明一个全局变量是有效的

#ifndef INC_MAIN_H_
#define INC_MAIN_H_

int my_var;

#endif 

但是给它分配一个默认值是行不通的:

#ifndef INC_MAIN_H_
#define INC_MAIN_H_

int my_var = 0;

#endif 

它在我包含此 main.h 的每个文件中显示多个编译错误

'my_var' 的多重定义;app/src/testfile.o:app/inc/main.h:4: 首先在这里定义

我知道以这种方式声明全局变量不是最佳实践,但我无法弄清楚为什么添加赋值会导致编译错误,而且我找不到明确的答案。

标签: cglobal-variablesheader-files

解决方案


使用您正在使用的构建工具和开关,int my_var;其行为主要类似于不是定义的声明。允许对象标识符的多个声明。

int my_var = 0;是一个定义。应该只有一个定义。

由于 C 的使用和开发历史,int my_var;在技术上是一个暂定定义。如果my_var翻译单元(正在编译的源文件,包括它包含的所有文件)中没有正则定义,则它充当正则定义。

但是,当您将其包含在多个源文件中的头文件中时,您就有了多个定义。当具有外部链接的同一对象标识符有多个定义时,C 标准不定义行为。

当有多个常规定义时,您的构建工具会报告错误。但是,它们以不同的方式处理来自暂定定义的定义:它们允许它们并将它们合并为一个定义。同样,这是由于 C 如何开发和使用的历史。此外,这种行为最近在 GCC 中发生了变化。在 GCC 版本 10 之前,默认情况下会合并暂定定义,如上所述。使用 GCC 10 及更高版本,暂定定义不会合并,多个定义将导致错误。可以使用 switch 请求旧的行为-fcommon

为避免暂定定义,您应该将标头中的标识符声明为extern int my_var;,这只是一个声明而不是暂定定义,并且您应该只有一个包含 的源文件int my_var = 0;,这是常规定义而不是暂定定义。

附加信息在这里这里这里


推荐阅读