我经常在头文件的开头看到这样的代码:
#ifndef HEADERFILE_H
#define HEADERFILE_H
在文件的末尾是
#endif
这样做的目的是什么?
#pragma
是什么:它激活特定于编译器的功能。尽管 #pragma once
得到了非常广泛的支持,但它是非标准的。
info cpp
或 look here)说“并非所有预处理器都能识别它,因此您不能在可移植程序中依赖它。”。并且 GNU cpp 优化了通用和可移植的 #ifndef
习惯用法,因此它与 #pragma once
一样高效。
#ifndef HEADERFILE_H
可以违反实现的命名空间,标题名称恰好以 E
开头;以 E
和数字或大写字母开头的标识符保留给 <errno.h>
。我建议#ifndef H_HEADERFILE
。
这些称为 #include guards。
包含标头后,它会检查是否定义了唯一值(在本例中为 HEADERFILE_H
)。然后,如果它没有定义,它会定义它并继续到页面的其余部分。
当再次包含该代码时,第一个 ifndef
失败,导致一个空白文件。
这可以防止重复声明任何标识符,例如类型、枚举和静态变量。
#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif
#ifndef
检查给定令牌是否在文件或包含的文件中较早出现 #defined
;如果没有,它包含它和结束 #else
之间的代码,或者,如果没有 #else
,则包含 #endif
语句。 #ifndef
通常用于使头文件具有幂等性,方法是在包含文件后定义一个标记并检查该标记是否未设置在该文件的顶部。
#ifndef _INCL_GUARD
#define _INCL_GUARD
#endif
#ifndef H_HEADER_NAME
的内容。
这可以防止多次包含相同的头文件。
#ifndef __COMMON_H__
#define __COMMON_H__
//header file content
#endif
假设您已将此头文件包含在多个文件中。所以第一次 __COMMON_H__ 没有定义,它将被定义并包含头文件。
下次定义 __COMMON_H__ 时,将不再包含。
它们被称为 ifdef 或包含警卫。
如果编写一个小程序,似乎不需要它,但是随着项目的增长,您可能会有意或无意地多次包含一个文件,这可能会导致编译警告,如已声明的变量。
#ifndef checks whether HEADERFILE_H is not declared.
#define will declare HEADERFILE_H once #ifndef generates true.
#endif is to know the scope of #ifndef i.e end of #ifndef
如果没有声明,这意味着#ifndef 生成true,那么只有#ifndef 和#endif 之间的部分执行,否则不执行。这将防止再次声明标识符、枚举、结构等......
#pragma once
做同样的事情:-)#pragma once
不可移植;建议使用常见的#ifndef
成语。#pragma once
是明确的;它说“一旦我#include
进入给定的翻译单元,就不要再打开这个文件了”。包含守卫说“如果我再次被包含,请跳过我的内容”(但文件仍然在逻辑上打开,从头到尾读取,并且守卫丢弃内容)。我没有检查最近的编译器,但是有一段时间,GCC 识别了包含保护习语并隐式地做了#pragma once
所做的事情,而 MSVC 没有,所以如果你也没有#pragma once
,你会打开并重复处理文件,增加系统调用开销。