http://en.wikipedia.org/wiki/Pragma_once
当所有这些编译器都支持#pragma once
时,我是否还应该使用包含保护?
很多关于堆栈溢出的响应都表示要使用它们兼容,但我不确定它是否仍然是真的。
今天哪些编译器不支持#pragma once
?
我不确定在它被Widley采用之前是否只是一个推荐,或者是否仍有很好的理由使用这两种方法。
仅使用#pragma once
的任何示例都会导致问题?
答案 0 :(得分:14)
这取决于您的程序预计可移植的程度。
只要您正在编写一个应该与编译器一起工作的程序,您知道肯定支持#prama once
,那么只需使用#pragma once
即可。但这样做可以将程序限制为支持实现定义功能的编译器集。
如果您的程序需要所有编译器,那么您应该使用#pragma once
并同时包含警卫。
如果编译器不支持#pragma once
,它将简单地忽略它 [Ref#1] ,在这种情况下,标题保护将为您服务的目的,所以没有错在您不了解目标编译器支持的功能时使用它们。
因此,如果您希望您的程序在不同编译器上100%可移植,那么理想的方法仍然是仅使用包含防护。由于@CharlesBailey正确指出,因为#pragma once
的行为是实现定义的,因此未知编译器上的行为可能会对您的程序产生不利影响。
[参考#1]
标准C ++ 03:16.6 Pragma指令
表单
的预处理指令
# pragma pp-tokensopt new-line
使实现以实现定义的方式运行。 忽略实现无法识别的任何编译指示。
答案 1 :(得分:10)
这是非标准的,所以如果你想安全使用包含警卫
答案 2 :(得分:6)
如您的表所示,现在很少遇到主流使用中不支持#pragma once
的编译器。为了保持代码库的清洁和廉价维护,需要不断进行重构。每次重命名一个类或移动一些代码时,必须更新包含警卫会给这项工作带来沉重的负担。
所以我会说除了一些利基角落案例或破坏构建系统#pragma once
实际上可以安全地依赖。如果您只关心生产力和代码质量,那么只使用#pragma once
似乎是明显的选择。
例外情况是,如果你正在编写一个需要在阳光下支持每个编译器的库,或者不幸的是必须使用其中一个没有此功能的稀有编译器。