Rya*_*rle 283 c++ include-guards
我已经读过使用时会有一些编译器优化,#pragma once
这会导致更快的编译.我认为这是非标准的,因此可能造成跨平台兼容性问题.
这是非Windows平台(gcc)上大多数现代编译器支持的东西吗?
我想避免平台编译问题,但也想避免后备警卫的额外工作:
#pragma once
#ifndef HEADER_H
#define HEADER_H
...
#endif // HEADER_H
Run Code Online (Sandbox Code Playgroud)
我应该担心吗?我是否应该在这方面进一步消耗精力?
Mot*_*tti 314
#pragma once
确实有一个缺点(除非是非标准的),如果你在不同的位置有相同的文件(我们有这个因为我们的构建系统复制文件),那么编译器会认为这些是不同的文件.
Zif*_*fre 171
使用#pragma once
应该适用于任何现代编译器,但我认为没有任何理由不使用标准#ifndef
包含保护.它工作得很好.一个警告是GCC #pragma once
在版本3.4之前不支持.
我还发现,至少在GCC上,它认识到标准#ifndef
包括后卫并对其进行优化,所以它不应该慢得多#pragma once
.
Mic*_*urr 58
我希望#pragma once
(或类似的东西)符合标准.包括警卫不是一个真正的大问题(但他们似乎有点难以向学习该语言的人解释),但这似乎是一个可以避免的轻微烦恼.
实际上,由于99.98%的时间,#pragma once
行为是期望的行为,如果防止多个包含头被编译器自动处理,带有#pragma
或允许双重包含的内容将会很好.
但是我们拥有的东西(除了你可能没有#pragma once
).
Jar*_*Par 34
我不知道任何性能优势,但它确实有效.我在所有的C++项目中使用它(授予我使用MS编译器).我发现它比使用更有效
#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif
Run Code Online (Sandbox Code Playgroud)
它执行相同的工作,并且不会使用其他宏填充预处理器.
GCC #pragma once
正式支持3.4版本.
uce*_*ern 22
#pragma once
自3.4以来GCC支持,请参阅http://en.wikipedia.org/wiki/Pragma_once以获得进一步的编译器支持.
我看到使用#pragma once
而不是包含警卫的巨大好处是避免复制/粘贴错误.
让我们面对现实:我们大多数人几乎不能从头开始新的头文件,而只是复制现有的头文件并根据我们的需要进行修改.使用#pragma once
而不是包含保护来创建工作模板要容易得多.我修改模板的次数越少,我就越不容易遇到错误.在不同的文件中包含相同的防护导致奇怪的编译器错误,并且需要一些时间来弄清楚出了什么问题.
TL; DR:#pragma once
更容易使用.
Jon*_*ler 11
使用' #pragma once
'可能没有任何影响(它在任何地方都不受支持 - 虽然它得到越来越广泛的支持),所以你需要使用条件编译代码,在这种情况下,为什么要打扰' #pragma once
'?无论如何,编译器可能会优化它.但它确实依赖于您的目标平台.如果你的所有目标都支持它,那么继续使用它 - 但它应该是一个有意识的决定,因为如果你只使用pragma然后移植到不支持它的编译器,那么所有地狱都会破裂.
Edw*_*vis 11
我使用它并且我很满意它,因为我必须输入更少的东西来制作新的标题.它在三个平台上运行良好:Windows,Mac和Linux.
我没有任何性能信息,但我相信#pragma和include guard之间的区别与解析C++语法的速度相比毫无结果.这是真正的问题.例如,尝试使用C#编译器编译相同数量的文件和行,以查看差异.
最后,使用后卫或者pragma,根本不重要.
性能优势在于,一旦读取了#pragma,就不必重新打开文件。使用警卫,编译器必须打开文件(这可能会花费很多时间),以获取不应再包含其内容的信息。
这只是理论上的原因,因为对于每个编译单元,某些编译器将不会自动打开没有任何读取代码的文件。
无论如何,并非所有编译器都如此,因此理想情况下,一旦跨平台代码完全不标准/没有标准化的定义和效果,就必须避免使用#pragma。但是,实际上,这确实比后卫更好。
最后,更好的建议是确保同时使用编译指示和防护,而不必在这种情况下检查每个编译器的行为,从而确保从编译器获得最佳速度。
#ifndef NR_TEST_H
#define NR_TEST_H
#pragma once
#include "Thing.h"
namespace MyApp
{
// ...
}
#endif
Run Code Online (Sandbox Code Playgroud)
这样一来,您可以同时兼顾两者(跨平台和帮助编译的速度)。
由于键入时间较长,我个人使用了一种工具来帮助您以一种非常灵巧的方式生成所有内容(Visual Assist X)。
小智 5
不总是.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52566有两个文件的好例子,两个文件都包含在内,但由于时间戳和内容相同(文件名不同),误认为是相同的.