#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议避免使用包含守卫的样板文件。