我还应该使用#includeguards和#pragma一次吗?

问题描述 投票:0回答:3

enter image description here

http://en.wikipedia.org/wiki/Pragma_once
当所有这些编译器都支持

#pragma once
时,我还应该使用包含防护吗?
关于堆栈溢出的很多回复都说要使用两者来实现兼容性,但我不确定这是否仍然正确。 现在哪些编译器不支持
#pragma once

我不确定使用这两种方法是否只是在被广泛采用之前的建议,或者是否仍然有充分的理由使用这两种方法。
有没有仅使用

#pragma once
会导致问题的例子?

c++ pragma include-guards
3个回答
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

使实现按照实现定义的方式运行。 任何未被实现识别的编译指示都会被忽略。


10
投票

它是非标准的,所以如果您想安全,请使用包含防护装置


7
投票

正如您的表格所示,现在很少遇到主流使用的编译器不支持

#pragma once
。为了保持代码库干净且维护成本低,需要不断地进行重构。每次重命名类或移动一些代码时都必须更新包含防护,这会给这项工作带来很大的负担。

所以我想说,除了一些特殊的极端情况或损坏的构建系统之外,

#pragma once
实际上是可以安全依赖的。如果您关心生产力和代码质量,则仅使用
#pragma once
似乎是显而易见的选择。

例外情况是,如果您正在编写一个需要支持世界上所有编译器的库,或者不幸的是必须使用不具有此功能的罕见编译器之一。

© www.soinside.com 2019 - 2024. All rights reserved.