#pragma曾经是C ++ 11标准的一部分吗?

时间:2014-05-16 13:20:25

标签: c++ c++11 macros header-files c++14

传统上,避免C ++中多个头部包含的标准和可移植方法是使用#ifndef - #define - #endif预编译器指令方案,也称为macro-guard scheme(参见下面的代码片段)。

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

在大多数实现/编译器中(见下图),有一个更“优雅”的替代方案,其作用与名为#pragma once的宏保护方案相同。与宏保护方案相比,#pragma once有几个优点,包括更少的代码,避免名称冲突,有时提高编译速度。

enter image description here

做了一些研究,我意识到虽然几乎所有已知的编译器都支持#pragma once指令,但#pragma once指令是否是C ++ 11标准的一部分仍然存在混淆。

问题:

  • 有人可以澄清#pragma once指令是否属于C ++ 11标准吗?
  • 如果它不是C ++ 11标准的一部分,是否有计划将其包含在以后的版本中(例如,C ++ 14或更高版本)?
  • 如果有人能够进一步详细说明使用其中一种技术(即,宏观保护与#pragma once)的优缺点,也会很好。

2 个答案:

答案 0 :(得分:98)

#pragma once 不是标准。这是一种普遍的(但不是 通用)扩展,可以使用

  • 如果您的可移植性问题有限,
  • 您可以确定所有包含文件始终位于本地磁盘上。

它被认为是标准化,但因为它而被拒绝 无法可靠地实施。 (问题发生在你身上 有文件可通过几个不同的远程坐骑访问。)

确保没有包含警卫是相当容易的 单一发展中的冲突。对于图书馆,可能 被许多不同的发展所使用,显而易见的解决方案是 为包含守卫生成大量随机字符 当你创建它。 (可以设置一个好的编辑器来执行此操作 你何时打开一个新的标题。)但即使没有这个, 我还没有遇到任何冲突问题 库。

答案 1 :(得分:32)

标准第16.6节(N3936草案)将#pragma指令描述为:

  

表单

的预处理指令
# pragma pp-tokensopt new-line
     

使实现在实现定义中表现   方式。该行为可能导致转换失败或导致   翻译或由此产生的程序表现为不符合   方式。任何未被实现识别的pragma是   忽略。

基本上#pragma once#pragma指令的特定于实现的实例,不,它不是标准的。然而。

它通常得到大多数“主要编译器”的广泛支持,包括GCCClang,因此有时建议避免使用包含防范的样板。