我读到过,使用#pragma一次可以优化编译器,从而加快编译速度。我知道这是不标准的,因此可能会带来跨平台兼容性问题。

非windows平台(gcc)上的大多数现代编译器都支持这一点吗?

我希望避免平台编译问题,但也希望避免备用保护的额外工作:

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

我应该担心吗?我还需要在这上面花费更多的精力吗?


当前回答

使用#pragma一次应该适用于任何现代编译器,但我不认为有任何理由不使用标准的#ifndef include guard。它工作得很好。需要注意的是,GCC在3.4版之前一次都不支持#pragma。

我还发现,至少在GCC上,它可以识别标准的#ifndef include guard并对其进行优化,因此它应该不会比#pragma慢很多。

其他回答

我不知道有什么性能上的好处,但它确实有效。我在我所有的c++项目中都使用它(当然我使用的是MS编译器)。我发现它比使用更有效

#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif

它做同样的工作,并且不使用额外的宏填充预处理器。

GCC在3.4版正式支持#pragma。

使用#pragma一次应该适用于任何现代编译器,但我不认为有任何理由不使用标准的#ifndef include guard。它工作得很好。需要注意的是,GCC在3.4版之前一次都不支持#pragma。

我还发现,至少在GCC上,它可以识别标准的#ifndef include guard并对其进行优化,因此它应该不会比#pragma慢很多。

Additional note to the people thinking that an automatic one-time-only inclusion of header files is always desired: I build code generators using double or multiple inclusion of header files since decades. Especially for generation of protocol library stubs I find it very comfortable to have a extremely portable and powerful code generator with no additional tools and languages. I'm not the only developer using this scheme as this blogs X-Macros show. This wouldn't be possible to do without the missing automatic guarding.

Using '#pragma once' might not have any effect (it is not supported everywhere - though it is increasingly widely supported), so you need to use the conditional compilation code anyway, in which case, why bother with '#pragma once'? The compiler probably optimizes it anyway. It does depend on your target platforms, though. If all your targets support it, then go ahead and use it - but it should be a conscious decision because all hell will break loose if you only use the pragma and then port to a compiler that does not support it.

GCC从3.4开始支持#pragma一次,参见http://en.wikipedia.org/wiki/Pragma_once获得进一步的编译器支持。

我认为使用#pragma一次而不是包含守卫的最大好处是可以避免复制/粘贴错误。

让我们面对这个问题:我们大多数人很少从头开始一个新的头文件,而只是复制一个现有的头文件并根据我们的需要进行修改。使用#pragma创建一个工作模板比使用守卫要容易得多。对模板的修改越少,遇到错误的可能性就越小。在不同的文件中使用相同的include守卫会导致奇怪的编译器错误,并且需要一些时间来找出哪里出了问题。

#pragma once更容易使用。