我读到过,使用#pragma一次可以优化编译器,从而加快编译速度。我知道这是不标准的,因此可能会带来跨平台兼容性问题。
非windows平台(gcc)上的大多数现代编译器都支持这一点吗?
我希望避免平台编译问题,但也希望避免备用保护的额外工作:
#pragma once
#ifndef HEADER_H
#define HEADER_H
...
#endif // HEADER_H
我应该担心吗?我还需要在这上面花费更多的精力吗?
我读到过,使用#pragma一次可以优化编译器,从而加快编译速度。我知道这是不标准的,因此可能会带来跨平台兼容性问题。
非windows平台(gcc)上的大多数现代编译器都支持这一点吗?
我希望避免平台编译问题,但也希望避免备用保护的额外工作:
#pragma once
#ifndef HEADER_H
#define HEADER_H
...
#endif // HEADER_H
我应该担心吗?我还需要在这上面花费更多的精力吗?
当前回答
我希望#pragma曾经(或类似的东西)出现在标准中。包含警卫并不是什么大问题(但向学习该语言的人解释它们似乎有点困难),但这似乎是一个可以避免的小麻烦。
事实上,因为在99.98%的情况下,#pragma once行为是理想的行为,如果编译器能自动处理防止一个头文件被多次包含,使用#pragma或其他允许重复包含的东西,那就更好了。
但是我们拥有我们所拥有的(除了你可能一次都没有#pragma)。
其他回答
GCC从3.4开始支持#pragma一次,参见http://en.wikipedia.org/wiki/Pragma_once获得进一步的编译器支持。
我认为使用#pragma一次而不是包含守卫的最大好处是可以避免复制/粘贴错误。
让我们面对这个问题:我们大多数人很少从头开始一个新的头文件,而只是复制一个现有的头文件并根据我们的需要进行修改。使用#pragma创建一个工作模板比使用守卫要容易得多。对模板的修改越少,遇到错误的可能性就越小。在不同的文件中使用相同的include守卫会导致奇怪的编译器错误,并且需要一些时间来找出哪里出了问题。
#pragma once更容易使用。
我使用#ifndef/#define include守卫使用包含UUID的符号,如下所示:
#ifndef ARRAY__H_81945CB3_AEBB_471F_AC97_AB6C8B220314
#define ARRAY__H_81945CB3_AEBB_471F_AC97_AB6C8B220314 /* include guard */
#endif
我一直使用能够自动生成uuid的编辑器。 这可以防止与其他库中具有相同基本名称的文件发生名称冲突,并检测文件系统中的多个位置是否放置了完全相同的文件。
缺点是增加了表的大小,因为符号要大得多,但我还没有看到它的问题。
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.
我使用它,我很高兴,因为我必须键入更少,使一个新的标题。它在Windows、Mac和Linux三个平台上都运行得很好。
我没有任何性能信息,但我相信,与解析c++语法的缓慢相比,#pragma和include守卫之间的差异将是微不足道的。这才是真正的问题。例如,尝试用c#编译器编译相同数量的文件和行,看看有什么不同。
最后,使用guard或pragma根本不重要。
如果我们使用msvc或Qt(到Qt 4.5),因为GCC(到3.4),msvc都支持#pragma一次,我可以看到没有理由不使用#pragma一次。
源文件名通常与类名相同,我们知道,有时我们需要重构,重命名类名,那么我们也必须改变#include XXXX,所以我认为手动维护#include xxxxx不是一个聪明的工作。即使使用Visual Assist X扩展,维护“xxxx”也不是一项必要的工作。