3

几乎所有 C++ 编译器都实现了非标准#pragma once功能,但 C++ 标准将其排除在外。

C++ 标准中排除了为什么#pragma once或某些语言结构的通常解释是硬链接和复制的头文件会破坏或激发编译器的启发式。公平地说,启发式算法通常与 C++ 哲学不兼容,但关于简单的破坏:有许多有用的语言特性可以破坏,不仅. 管理此类损坏的正常 C++ 方法是让编译器在可疑情况下发出可选警告。毕竟,C++ 的设计目的是让一个程序在希望这样做时不安全和/或不可移植。此外,它的不安全性和/或不可移植性非常小。只是没那么容易被滥用。#pragma once#pragma once#pragma once#pragma once

当通常包含其他可滥用但有用的语言功能时,为什么将其#pragma once排除在标准之外? 有什么特别之处吗?#pragma once

另外,在哪里可以阅读标准委员会最近对此事的审议?是否有某个委员会成员或委员会追随者发表了最近的辩论摘要?

4

2 回答 2

3

有几个简单的原因:

  1. 实现和指定它比通常假设的要难。实现它的论点并没有多少水,因为实现通常不处理颠覆该功能的方法。
  2. 与尝试改进我们想要摆脱的东西相比,委员会的时间更合理地花在处理使大部分预处理器变得不必要的模块上。
  3. 有一个简单的解决方法(包括警卫),因为没有#pragma once,即它不被认为是一个问题。
  4. 看来,现有的实现实际上确实表现不同,这似乎是最近讨论之一的根源。当然,这意味着标准化会很好,但它会立即开始与 2 ​​发生冲突。讨论不会简单,因为不同的各方都希望保留他们各自的行为。
  5. 我没有做太彻底的搜索,但我也没有看到提案:如果没有人写提案[并在整个过程中游说],那么任何事情都不会标准化。也就是说,我完全希望上面给出的停止提案的理由#pragma once有足够的多数,以便很快停止。

最近有关于提案邮件列表的讨论(请参阅isocpp.org了解如何注册;不过,我目前无法访问该站点)。不过,我并没有太彻底地遵循它。快速浏览一下我看到了上面给出的四个原因(我浏览后添加的第四个)。

以下是最近邮件列表讨论中的一些参考资料:

  1. #pragma 曾经是标准的一部分吗?
  2. 为什么 C/C++s #pragma 不是标准的?
  3. 模块提案
于 2014-10-26T15:17:53.727 回答
2

据我了解,是标准指令第 16.6 节(草案)中描述#pragma once的标准指令的实现特定实例:#pragma

16.6 Pragma 指令 [cpp.pragma]

形式的预处理指令

# pragma pp-tokens opt new-line 导致实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不合格的方式运行。任何未被实现识别的编译指示都会被忽略。

标准化pragma once会引入相当多的复杂性。在这里也看看:https ://stackoverflow.com/a/1696194/2741329

于 2014-10-26T15:24:00.250 回答