多余包含必要的警卫?

时间:2010-02-09 23:46:28

标签: c++ include include-guards c++builder-2009

Codegear RAD Studio 2009中是否需要“冗余包括警卫”?编译器是否足够聪明,可以自行处理?

例如,我可能在foo.h中有以下'include guard':

#ifndef fooH
#define fooH
// ... declaration here
#endif

以及use_foo.h中的以下'冗余包含保护':

#ifndef fooH
    #include "foo.h"
#endif

此外,如果编译器不够智能,如果它们包含在源文件中,那么“冗余包括警卫”是必需的。例如use_foo.cpp。 ?

3 个答案:

答案 0 :(得分:5)

您标记为“冗余包含保护”的代码部分不是必需的,但它是可能的优化。

在C ++ Builder的情况下,有检测标题保护的逻辑,所以它不是必需的。

在一般情况下,无论如何,预处理过程通常非常快,因此无论如何优化都不太可能为您带来任何好处。

答案 1 :(得分:3)

这些冗余包含防护旨在模拟建议的#pragma once指令的功能:如果已经包含某个头文件,那么预处理器甚至不会再尝试查找,打开和解析它(因为它必须与“普通”包括防守技术)。在许多情况下,这使得包含文件的处理更加有效(加快编译速度)。

这种方法显然是一种高维护方法:必须确保保护符号的拼写在头文件内以及外部完全相同。

答案 2 :(得分:2)

正如你所说的那样,“冗余包括守卫”会加速编译。

如果没有冗余保护,编译器将迭代整个foo.h文件,查找可能在#ifndef块之外的一些代码。如果它是一个长文件,并且这很多地方,编译器可能会浪费很多时间。但是使用冗余防护,它可以跳过整个#include语句,甚至不会重新打开该文件。

当然,你必须进行实验,看看编译器在foo.h中迭代而不是实际编译任何内容所浪费的实际时间。也许现代编译器实际上会寻找这种模式并且自动知道根本不打算打开文件,我不知道。

(开始编辑280Z28)

至少 GCC和MSVC识别以下标题结构。使用这种模式几乎可以抵消包含文件中的警卫所带来的所有好处。请注意,当编译器检查结构时,将忽略注释。

// GCC will recognize this structure and not reopen the file
#ifndef SOMEHEADER_H_INCLUDED
#define SOMEHEADER_H_INCLUDED

// Visual C++ uses #pragma once to mark headers that shouldn't be reopened
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#   pragma once
#endif

// header text goes here.

#endif

(结束编辑)