【发布时间】:2017-11-21 14:04:43
【问题描述】:
所以我最近在我工作的地方进行了一次讨论,其中我质疑使用 双重 包含防护而不是单一防护。我所说的双重保护的意思如下:
头文件,“header_a.hpp”:
#ifndef __HEADER_A_HPP__
#define __HEADER_A_HPP__
...
...
#endif
当在任何地方包含头文件时,无论是在头文件中还是在源文件中:
#ifndef __HEADER_A_HPP__
#include "header_a.hpp"
#endif
现在我明白在头文件中使用保护是为了防止多次包含已定义的头文件,它很常见并且有据可查。如果宏已定义,则编译器会将整个头文件视为“空白”,并防止双重包含。很简单。
我不明白的问题是在#include "header_a.hpp" 周围使用#ifndef __HEADER_A_HPP__ 和#endif。同事告诉我,这为夹杂物增加了第二层保护,但如果第一层绝对能完成这项工作(或确实能做到?),我看不出第二层有什么用处。
我能想到的唯一好处是它完全阻止了链接器查找文件的麻烦。这是为了缩短编译时间(没有提到它的好处),还是这里有其他我没有看到的东西在起作用?
【问题讨论】:
-
这只是给代码增加了另一层脆弱性。第二层完全没有必要。
-
不是链接器,而是预处理器。老实说,如果你只包含你需要的东西,在现代构建系统上,任何这样的好处对我来说都是微不足道的。老实说,他的“解释”更像是一个专家初学者。
-
曾几何时,可能有一两个编译器愚蠢到每次都打开文件来检查包含保护。在这个千年中生产的编译器不会这样做,因为它可以只保留一个文件表并包含警卫并在打开文件之前查阅它。
-
完全没有必要。一点好处都没有。
-
请注意,包含两个连续下划线 (
__HEADER_A_HPP__) 的名称和以下划线后跟大写字母的名称保留供实现使用。不要在你的代码中使用它们。