c - 变量定义应该在头文件中吗?

标签 c linker c-preprocessor header-files include-guards

我对 C 和编译过程的非常基础的知识最近已经生锈了。我试图找出以下问题的答案,但我无法连接编译、链接和预处理阶段的基础知识。在谷歌上快速搜索也没有太大帮助。所以,我决定来最终的知识来源:)

我知道: 不应在 .h 文件中定义变量。可以在那里声明它们。

原因:因为头文件可能会从多个地方被包含,从而多次重新定义变量(链接器给出错误)。

可能的解决方法:在头文件中使用头文件保护并在其中定义变量。

这真的是一个解决方案吗: 不是。因为 header-guards 用于预处理阶段。也就是告诉编译器这部分已经包含了,不要再包含了。但是我们的多重定义错误出现在链接器部分 - 在编译之后。

这整件事让我对预处理和链接的工作方式感到困惑。我认为如果已经定义了标题保护符号,预处理将不会包含代码。那样的话,一个变量的多重定义问题是不是也可以解决了?

如果这些预处理指令使编译过程免于在 header 保护下重新定义符号,但链接器仍然获得符号的多个定义,会发生什么情况?

最佳答案

我过去用过的一件事(当全局变量流行时):

var.h文件:

...
#ifdef DEFINE_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int global1;
EXTERN int global2;
...

然后在一个 .c 文件中(通常是包含 main() 的文件):

#define DEFINE_GLOBALS
#include "var.h"

其余的源文件通常只包含“var.h”。

请注意,DEFINE_GLOBALS 不是标题保护,而是允许根据变量是否已定义来声明/定义变量。这种技术允许声明/定义的一个副本。

关于c - 变量定义应该在头文件中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2216765/

相关文章:

c - 字符串突变的简单案例

c - 区分设备断开超时

ios - 使用 Ionic Package Build 和 XCode 8 在 iOS 构建中出现重复符号错误

c - 如何制作#define 函数的循环?

从数字变量值生成标记的 C 宏

C 预处理器令人困惑的行为

c - 特殊的结果。 #1-13 C 编程语言书籍

c预处理器将多个参数作为一个参数传递

c++ - 为什么 C++ 链接器允许未定义的函数?

c - 编译 MEX 文件时出现链接问题