C语言 变量定义应该在头文件中吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2216765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should variable definition be in header files?
提问by Methos
My very basic knowledge of Cand 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 :)
我对C和编译过程的基本知识最近变得生疏了。我试图找出以下问题的答案,但我无法连接编译、链接和预处理阶段的基础知识。在谷歌上快速搜索也没有多大帮助。所以,我决定来到知识的最终来源:)
I know:Variables should not be defined in the .h files. Its ok to declare them there.
我知道:不应在 .h 文件中定义变量。可以在那里声明它们。
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?
这些预处理指令使编译过程免于在头文件保护下重新定义符号,但链接器仍然获得符号的多个定义,会发生什么?
采纳答案by Jay
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.
Header Guard 保护您免受单个源文件中的多个包含,而不是多个源文件。我猜你的问题源于不理解这个概念。
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.
并不是说预处理器守卫在编译时从这个问题中得到了节省。实际上在编译期间,只有一个源文件被编译成一个 obj,符号定义没有被解析。但是,在链接器尝试解析符号定义时进行链接的情况下,看到多个定义导致它标记错误时会感到困惑。
回答by Richard Pennington
One thing that I've used in the past (when global variables were in vogue):
我过去使用过的一件事(当全局变量流行时):
var.h file:
var.h 文件:
...
#ifdef DEFINE_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int global1;
EXTERN int global2;
...
Then in one.c file (usually the one containing main()):
然后在一个.c 文件中(通常是包含 main() 的文件):
#define DEFINE_GLOBALS
#include "var.h"
The rest of the source files just include "var.h" normally.
其余的源文件通常只包含“var.h”。
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.
请注意, DEFINE_GLOBALS 不是标题保护,而是允许根据是否已定义来声明/定义变量。这种技术允许声明/定义的一个副本。
回答by bmargulies
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.
您有两个 .c 文件。它们分别编译。每一个都包含你的头文件。一次。每个人都有一个定义。它们在链接时发生冲突。
The conventional solution is:
传统的解决方案是:
#ifdef DEFINE_SOMETHING
int something = 0;
#endif
Then you #define DEFINE_SOMETHING in only one.c file.
然后你只在一个.c 文件中#define DEFINE_SOMETHING 。
回答by bmargulies
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.
头文件保护阻止一个头文件被多次包含在同一个翻译单元中(即在同一个 .c 源文件中)。如果您将文件包含在两个或多个翻译单元中,它们将不起作用。

