Why are #ifndef and #define used in C++ header files?
我一直在头文件的开头看到这样的代码:
1 2
| #ifndef HEADERFILE_H
#define HEADERFILE_H |
并在文件的最后是
这样做的目的是什么?
-
+1 - 我也有同样的疑问,在这里得到了更好的答案,可能对未来的访问者有用:stackoverflow.com/q/3246803/1134940
-
我想补充一点,你也可以使用#pragma一次,这就是你所要做的,它与ifndef的用途相同。有关两者的比较,请参阅:stackoverflow.com/questions/1143936/…
-
最好提一下#pragma是什么:它激活了特定于编译器的功能。虽然#pragma once得到广泛支持,但它是非标准的。
-
@Dimension:GNU自己的文档(info cpp或者在这里看到)说"它不被所有预处理器识别,所以你不能在便携式程序中依赖它。" GNU cpp优化了常见的便携式#ifndef习惯用法,因此它与#pragma once一样高效。
-
要考虑的一些事项:不要使用以下划线开头的宏名称;这些标识符保留给实现。更巧妙地,#ifndef HEADERFILE_H可以违反实现的头名称命名空间恰好以E开头;以E开头的标识符和数字或大写字母保留给。我建议#ifndef H_HEADERFILE。
-
以下是这些预定义的最简单描述。核实
这些被称为#include警卫。
包含标头后,它会检查是否定义了唯一值(在本例中为HEADERFILE_H)。然后,如果未定义,则定义它并继续到页面的其余部分。
再次包含代码时,第一个ifndef失败,导致出现空白文件。
这可以防止双重声明任何标识符,例如类型,枚举和静态变量。
-
Koning Baard XIV:VC甚至有#pragma once也是如此:-)
-
它还可以防止递归包含......想象一下,"alice.h"包含"bob.h","bob.h"包含"alice.h",它们没有包含警戒......
-
@Kevin:这就是我的意思。我想操纵一个由表单打开来操作的表单。它给了我很多错误,我不知道该怎么做。我放弃了=)
-
@?ouеу:#pragma once不便携;推荐使用常见的#ifndef成语。
-
多次包含标题有什么问题?假设没有递归包含...是同名变量的问题,还是只是一个更大的exe文件的问题?
-
@CIsForCookies将"一个定义规则"打入您最喜爱的搜索引擎。
1 2 3 4 5
| #ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif |
#ifndef检查给定标记在文件或包含文件中是否早于#defined;如果没有,它包括它与结束#else之间的代码,或者,如果没有#else,则包含#endif语句。 #ifndef通常用于通过在包含文件后定义令牌并检查令牌未设置在该文件的顶部来使头文件具有幂等性。
1 2 3
| #ifndef _INCL_GUARD
#define _INCL_GUARD
#endif |
-
保留以下划线开头的标识符;你不应该自己定义它们。使用#ifndef H_HEADER_NAME之类的东西。
-
我知道这是一个旧的注释,但实际上下划线限制仅适用于"外部标识符" - 可能最终出现在编译对象的符号表中的标识符,即全局变量和函数名称。它不适用于宏名称。
-
斯图的评论是真的吗?我刚看了stackoverflow.com/questions/228783/…现在我不太确定
这可以防止多次包含相同的头文件。
1 2 3 4
| #ifndef __COMMON_H__
#define __COMMON_H__
//header file content
#endif |
假设您已将此头文件包含在多个文件中。所以第一次
__COMMON_H__未定义,它将被定义并包含头文件。
下次定义__COMMON_H__时,它将不再包含。