由于其他可滥用但有用的功能已经标准化,为什么不#pragma一次?

时间:2014-10-26 15:06:23

标签: c++ pragma include-guards

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

The usual explanation为什么#pragma once,或者某些语言​​构造做了#pragma once做的事情,已从C ++标准中排除,硬链接和复制的头文件要么中断{{1}或者激发编译器启发式。公平地说,启发式算法通常与C ++哲学不相容,但对于普通破坏:有许多有用的语言特性可以打破,而不仅仅是#pragma once。管理此类破坏的正常C ++方法是让编译器在可疑实例中发出可选警告。毕竟,C ++是专门设计的,当一个程序希望这样做时,让一个程序不安全和/或不可移植。此外,#pragma once的不安全和/或不可移植性非常小。它只是不容易滥用。

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

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

2 个答案:

答案 0 :(得分:3)

有几个简单的原因:

  1. 比通常假设实现和指定它更难。由于实施通常不涉及颠覆该特征的方法,因此实施它的论点并不含水。
  2. 委员会时间更合理地用于处理模块,这些模块使得大多数预处理器不需要尝试改进我们想要摆脱的东西。
  3. 由于#pragma once的缺席,有一个简单的解决方法(包括警卫),即它不被认为是一个问题。
  4. 看来,现有的实现确实表现不同,这似乎是最近一次讨论的根源。当然,这意味着标准化会很好,但随后它会立即与2发生冲突。讨论不会很简单,因为不同的各方都希望保留各自的行为。
  5. 我没有进行过于彻底的搜索,但我也没有看到提案:如果没有人写一个提案[并且通过这个过程游说它],那么什么都不会标准化。也就是说,我完全相信上面给出的理由可以阻止添加#pragma once的提案有足够多的时间让它很快停止。
  6. 最近有关于提案邮件列表的讨论(请参阅isocpp.org了解如何注册;但此刻我无法访问此网站)。但是,我并没有彻底地遵循它。快速浏览它我看到了上面给出的四个原因(我在浏览后添加了第四个原因)。

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

    1. Is #pragma once part of the standard?
    2. Why isn't C/C++s #pragma once standard?
    3. modules proposal

答案 1 :(得分:2)

根据我的理解,#pragma once是标准#pragma指令的实现特定实例,如标准的第16.6节(draft)中所述:

  

16.6 Pragma指令[cpp.pragma]

     

表单

的预处理指令      

#pragma pp-tokens opt new-line导致实现在实现中表现 -   定义的方式。该行为可能会导致翻译   失败或导致翻译或结果程序表现出来   不合规的方式。任何未被识别的编译指示   实施被忽略。

标准pragma once会带来相当多的复杂性。 再看一下:https://stackoverflow.com/a/1696194/2741329