5

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

例如,我可能在 foo.h 中有以下“包含守卫”:

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

以及 use_foo.h 中的以下“冗余包含守卫”:

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

此外,如果编译器不够聪明,如果它们被包含在源文件中,是否需要“冗余包含保护”。例如use_foo.cpp。?

4

3 回答 3

5

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

在 C++Builder 的情况下,有检测标头保护的逻辑,因此不需要。

在一般情况下,预处理过程通常非常快,所以无论如何这种优化不太可能给你带来很多好处。

于 2010-02-10T17:45:25.927 回答
3

这些多余的包含保护旨在模拟提议#pragma once指令的功能:如果某些头文件已经被包含,那么预处理器甚至不会再尝试定位、打开和解析它(因为它必须使用“普通”包括后卫技术)。在许多情况下,这使得包含文件的处理更加高效(加速编译)。

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

于 2010-02-09T23:54:01.200 回答
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

(结束编辑)

于 2010-02-09T23:48:39.140 回答