首页 文章

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

提问于
浏览
126

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

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

然而,在大多数实现/编译器中(见下图),有一个更多的"elegant"替代方案与宏监护方案#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 回答

  • 31

    #pragma once 不标准 . 它是一种广泛的(但不是通用的)扩展,可以使用

    • 如果您的可移植性问题有限,并且

    • 您可以确保所有包含文件始终位于本地磁盘上 .

    它被认为是标准化,但被拒绝,因为它无法可靠地实施 . (当您通过多个不同的远程安装程序访问文件时会出现问题 . )

    确保在单个开发中不存在包含保护冲突是相当容易的 . 对于可能被许多不同开发项目使用的库,显而易见的解决方案是在创建包含防护时生成大量随机字符 . (无论何时打开新 Headers ,都可以设置一个好的编辑器来执行此操作 . )但即使没有这个,我还没有遇到任何库之间冲突的问题 .

  • 95

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

    #pragma pp-tokensopt new-line形式的预处理指令
    导致实现以实现定义的方式运行 . 该行为可能导致转换失败或导致转换程序或生成的程序以不符合的方式运行 . 将忽略实现无法识别的任何编译指示 .

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

    它通常得到大多数人的支持,包括GCCClang,因此有时建议避免使用包含防范的样板 .

相关问题