c - 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: 首先在这里定义
我知道以这种方式声明全局变量不是最佳实践,但我无法弄清楚为什么添加赋值会导致编译错误,而且我找不到明确的答案。
解决方案
使用您正在使用的构建工具和开关,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;
,这是常规定义而不是暂定定义。
推荐阅读
- android - React Native 应用程序中的通知声音设置对话框,例如 WhatsApp
- c# - Visual Studio 2019 中的“项目位置”设置存储在哪里?
- python - 无法从 python 计算器获得正确的输出
- automation - ansible 角色的常见用例
- python-3.x - 这个循环不会执行它之后的代码
- c++ - 在 c++ 中,将取消引用的后自增指针分配给另一个已取消引用的后自增指针的结果是什么?
- excel - “1004”:该排序引用无效。确保它在您要排序的数据内,并且第一个排序依据框不是相同的或空白的
- node.js - 保持获取最新数据
- arrays - 在视图控制器上放置无限的 uiview 对象数组
- android - Android以编程方式将域和IP添加到主机文件