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

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

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

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

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


当前回答

如今,老式的include守卫就像#pragma一样快。即使编译器没有特别对待它们,当它看到#ifndef WHATEVER和WHATEVER被定义时,它仍然会停止。现在打开一个文件非常便宜。即使有改进,也只是毫秒级的改进。

我只是不使用#pragma一次,因为它没有任何好处。为了避免与其他include守卫发生冲突,我使用了如下代码:CI_APP_MODULE_FILE_H——> CI =公司首字母;APP =应用程序名称;其余部分不言自明。

其他回答

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

#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif

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

GCC在3.4版正式支持#pragma。

如果我们使用msvc或Qt(到Qt 4.5),因为GCC(到3.4),msvc都支持#pragma一次,我可以看到没有理由不使用#pragma一次。

源文件名通常与类名相同,我们知道,有时我们需要重构,重命名类名,那么我们也必须改变#include XXXX,所以我认为手动维护#include xxxxx不是一个聪明的工作。即使使用Visual Assist X扩展,维护“xxxx”也不是一项必要的工作。

#pragma once确实有一个缺点(除了不是标准的),那就是如果你在不同的位置有相同的文件(我们有这样的情况是因为我们的构建系统会四处复制文件),那么编译器会认为这些是不同的文件。

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

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

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

#pragma once更容易使用。

不总是正确的。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52566有一个很好的例子,其中包括两个文件,但由于时间戳和内容相同(不相同的文件名),误以为它们是相同的。