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

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

 #ifndef MY_HEADER_HPP #define MY_HEADER_HPP ... #endif 

然而,在大多数的实现/编译器中(见下图),还有一个更为“优雅”的select,与macros观保护机制#pragma once有相同的作用。 与macros保护scheme相比, #pragma once有过几个优点,包括代码less,避免了名称冲突,有时也提高了编译速度。

在这里输入图像说明

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

问题:

  • 有人能澄清一下, #pragma once指令是否是C ++ 11标准的一部分?
  • 如果它不是C ++ 11标准的一部分,是否有计划在更新的版本上包含它(例如,C ++ 14或更高版本)?
  • 如果有人能够进一步阐述使用其中一种技术(例如,macros观防范与#pragma once )的优点/缺点,那也不错。

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

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

它被认为是标准化的,但被拒绝了,因为它不能被可靠地执行。 (当通过多个不同的远程装载可以访问文件时,会发生问题。)

确保单个开发中不存在警惕冲突是相当容易的。 对于可能被许多不同开发者使用的库,显而易见的解决scheme是在创build包含守卫时为其生成大量随机字符。 (每当你打开一个新的头文件时,一个好的编辑器可以设置为这样做。)但即使没有这个,我还没有遇到任何与库之间冲突的问题。

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

表单的预处理指令

 # pragma pp-tokensopt new-line 

导致实现以实现定义的方式运行。 这种行为可能会导致翻译失败,或者导致翻译者或由此产生的程序不合规的行为。 任何不被实现识别的编译指示都将被忽略。

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

它通常得到了包括GCC和Clang在内的大多数“主要编译器”的广泛支持,因此有时build议避免使用包含守卫的样板文件。