变量定义应该在头文件中吗?
我对C和编译过程的基本知识最近已经生锈了。我试图找出以下问题的答案,但无法连接编译、链接和预处理阶段的基础知识。在谷歌上的快速搜索也没有多大帮助。所以,我决定来到知识的终极来源:)
我知道: 不应在 .h 文件中定义变量。在那里声明它们就可以了。
原因:因为头文件可能会从多个位置包含,从而多次重新定义变量(链接器给出错误)。
可能的解决方法:在头文件中使用头保护并在其中定义变量。
这真的是一个解决方案吗: 不。因为 header-guards 用于预处理阶段。就是告诉编译器这部分已经被包含了,不要再包含了。但是我们的多重定义错误出现在链接器部分 - 编译之后很久。
这整件事让我对如何进行预处理和处理感到困惑。链接工作。我认为如果已经定义了标头保护符号,则预处理将不包括代码。那么,变量的多重定义问题不也应该得到解决吗?
如果这些预处理指令使编译过程免于在标头保护下重新定义符号,但链接器仍然获得符号的多个定义,会发生什么情况?
My very basic knowledge of C and compilation process has gone rusty lately. I was trying to figure out answer to the following question but I could not connect compilation, link and pre-processing phase basics. A quick search on the Google did not help much either. So, I decided to come to the ultimate source of knowledge :)
I know: Variables should not be defined in the .h files. Its ok to declare them there.
Why: Because a header file might get included from multiple places, thus redefining the variable more than one time (Linker gives the error).
Possible work-around: Use header-guards in header files and define variable in that.
Is it really a solution: No. Because header-guards are for preprocessing phase. That is to tell compiler that this part has been already included and do not include it once again. But our multiple definition error comes in the linker part - much after the compilation.
This whole thing has got me confused about how preprocessing & linking work. I thought that preprocessing will just not include the code, if the header guard symbol has been defined. In that case, shouldn't multiple definition of a variable problem also get solved?
What happens that these preprocessing directives save the compilation process from redefining symbols under header guards, but the linker still gets multiple definitions of the symbol?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我过去使用过的一件事(当全局变量流行时):
var.h 文件:
然后在 一个 .c 文件中(通常是包含 main() 的文件):
其余的源文件通常只包含“var.h”。
请注意,DEFINE_GLOBALS 不是标头保护,而是允许根据是否定义来声明/定义变量。该技术允许声明/定义的一份副本。
One thing that I've used in the past (when global variables were in vogue):
var.h file:
Then in one .c file (usually the one containing main()):
The rest of the source files just include "var.h" normally.
Notice that DEFINE_GLOBALS is not a header guard, but rather allows declaring/defining the variables depending on whether it is defined. This technique allows one copy of the declarations/definitions.
标头防护可保护您免受单个源文件中的多次包含,而不是多个源文件的影响。我想你的问题源于不理解这个概念。
这并不是说预处理器防护在编译时会因此问题而保存。实际上,在编译时,只有一个源文件被编译成一个 obj,符号定义没有被解析。但是,在链接的情况下,当链接器尝试解析符号定义时,它会因为看到多个定义而感到困惑,从而导致标记错误。
Header guard protects you from multiple inclusions in a single source file, not from multiple source files. I guess your problem stems from not understanding this concept.
It is not that pre-processor guards are saving during the compile time from this problem. Actually during compile time, one only source file gets compiled into an obj, symbol definitions are not resolved. But, in case of linking when the linker tries to resolve the symbol definitons, it gets confused seeing more than one definition casuing it to flag the error.
您有两个 .c 文件。它们单独编译。每一个都包含您的头文件。一次。每个人都有一个定义。它们在链接时发生冲突。
传统的解决方案是:
然后在仅一个.c 文件中#define DEFINE_SOMETHING。
You have two .c files. They get compiled separately. Each one includes your header file. Once. Each one gets a definition. They conflict at link time.
The conventional solution is:
Then you #define DEFINE_SOMETHING in only one .c file.
标头防护阻止标头文件在同一个翻译单元中多次包含(即在同一个 .c 源文件中)。如果您将文件包含在两个或多个翻译单元中,它们将不起作用。
Header guards stop a header file being included multiple times in the same translation unit (i.e. in the same .c source file). They have no effect if you include the file in two or more translation units.