http://en.wikipedia.org/wiki/Pragma_once
当所有这些编译器都支持时,我还应该使用包含防护#pragma once
吗?
很多关于堆栈溢出的响应都说要同时使用两者以实现兼容性,但我不确定这是否仍然正确。今天的编译器不支持#pragma once
什么?
我不确定使用这两种方法是否只是在被广泛采用之前的建议,或者是否仍然有很好的理由使用这两种方法。
仅在何时使用#pragma once
会导致问题的任何示例?
http://en.wikipedia.org/wiki/Pragma_once
当所有这些编译器都支持时,我还应该使用包含防护#pragma once
吗?
很多关于堆栈溢出的响应都说要同时使用两者以实现兼容性,但我不确定这是否仍然正确。今天的编译器不支持#pragma once
什么?
我不确定使用这两种方法是否只是在被广泛采用之前的建议,或者是否仍然有很好的理由使用这两种方法。
仅在何时使用#pragma once
会导致问题的任何示例?
这取决于您的程序的可移植性。
只要您正在编写一个应该与您知道肯定支持的编译器一起工作的程序#prama once
,只需使用#pragma once
就足够了。但是这样做会将您的程序限制为支持实现定义功能的编译器集。
如果您需要您的程序在所有编译器上工作,那么您应该同时使用#pragma once
并包含防护。
如果编译器不支持#pragma once
它,它将简单地忽略它[Ref#1],在这种情况下,标头保护将为您服务,因此当您不知道目标编译器支持的功能时,使用它们并没有错.
因此,如果您希望您的程序在不同的编译器上 100% 可移植,理想的方法仍然是仅使用包含防护。正如@CharlesBailey 正确指出的那样,由于 for 的行为#pragma once
是实现定义的,因此未知编译器上的行为可能会对您的程序产生不利影响。
[Ref#1]
标准 C++03:16.6 Pragma 指令
形式的预处理指令
# pragma pp-tokensopt new-line
导致实现以实现定义的方式运行。任何未被实现识别的编译指示都会被忽略。
它是非标准的,因此如果您想安全使用包含防护装置
如您的表所示,现在很少遇到不支持的主流使用编译器#pragma once
。为了保持代码库的清洁和维护成本低廉,需要不断地进行重构。每次重命名类或移动一些代码时都必须更新包含守卫,这给这项工作增加了很大的负担。
所以我想说,除了一些小众角落案例或损坏的构建系统#pragma once
在实践中是可以安全依赖的。如果您关心生产力和代码质量,则使用 only#pragma once
似乎是显而易见的选择。
例外情况是,如果您正在编写一个库,该库需要支持阳光下的每个编译器,或者不幸不得不使用这些不具备此功能的罕见编译器之一。