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

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

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

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

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


当前回答

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

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

其他回答

我使用#ifndef/#define include守卫使用包含UUID的符号,如下所示:

#ifndef ARRAY__H_81945CB3_AEBB_471F_AC97_AB6C8B220314
#define ARRAY__H_81945CB3_AEBB_471F_AC97_AB6C8B220314 /* include guard */


#endif

我一直使用能够自动生成uuid的编辑器。 这可以防止与其他库中具有相同基本名称的文件发生名称冲突,并检测文件系统中的多个位置是否放置了完全相同的文件。

缺点是增加了表的大小,因为符号要大得多,但我还没有看到它的问题。

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

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

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

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

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.

我使用它,我很高兴,因为我必须键入更少,使一个新的标题。它在Windows、Mac和Linux三个平台上都运行得很好。

我没有任何性能信息,但我相信,与解析c++语法的缓慢相比,#pragma和include守卫之间的差异将是微不足道的。这才是真正的问题。例如,尝试用c#编译器编译相同数量的文件和行,看看有什么不同。

最后,使用guard或pragma根本不重要。