【问题标题】:Are compilers allowed to support a feature, that is removed in the standard?是否允许编译器支持标准中删除的功能?
【发布时间】:2020-08-03 11:14:34
【问题描述】:

在第一段cppreference.com 中明确指出throw(T1, ..., Tn) 在C++17 中被删除。

令我困惑的是,一些编译器在 C++17 模式下支持 throw(T1, ..., Tn) (see demo)。

  • MSVC 默认支持它,但您可以为其打开警告,请参阅C5040。可以使用/we5040 将其转换为错误。
  • Clang 默认将其报告为错误,但可以使用-Wno-dynamic-exception-spec 关闭错误。
  • GCC 让您别无选择:这是一个错误。

是否允许编译器支持标准中删除的功能?目的是什么?

或者这只是一个编译器扩展,比如 GCC 中的void foo(int size) { char a[size]; },参见demo

【问题讨论】:

  • 没有一个 C++ 编译器可以考虑为“标准”C++ 编译器,虽然它们都试图遵循标准,但在某些地方行为可能会有所不同。您遇到的只是编译器不同的示例之一,但 Clang 默认行为和 GCC 似乎正确引发编译错误。
  • @rustyx:谢谢,我忽略了这一点。我从问题中删除了这部分,因为它显然是 cppreference.com 中的一个错字。
  • 编译器并不局限于支持 c++ 标准。所有这些编译器都有不遵守规则的编译选项(默认情况下有一些)。这个案子对我来说似乎没有什么不同。
  • 那么“标准”实际上标准化了什么?是否有一个编译器需要支持才能被称为“有效的 c++17(或 c++14/20 等)”编译器的列表?
  • @Roy2511 “需要支持的事物列表”就是标准本身。该标准标准化了想要称自己为“有效的 C++xx 编译器”的程序以及它们生成的程序的行为。

标签: c++ c++17 language-lawyer exception-specification


【解决方案1】:

是否允许编译器支持标准中删除的功能?

标准不允许这样做。一般来说,AFAIK 不会对语言中曾经的功能进行任何特殊处理(不会将它们与不存在的功能区分开来)。

如果编译器未使用特定配置(即特定标志)诊断此错误(即不给出错误或警告),则它不符合该配置中的标准。


出于什么目的?

向后兼容性(还有什么可能)。更具体地说,它允许您在同一个翻译单元中同时使用新旧功能。

如果您使用的库在其标头中使用了已删除的功能,但希望在您自己的代码中使用新的语言功能,这可能会很有用。

或者如果您出于某种原因想在自己的代码中使用已删除的功能以及新功能。


请注意,绝对符合标准实际上是不可能实现的。

一些编译器供应商比其他编译器供应商更关心一致性。微软往往不太关心它(或者至少习惯了,他们一直在努力)。

【讨论】:

  • MS 确实如此,但据称在 C++17 之前标准没有改变,因此他们只会在您使用该模式或最新模式时发出警告。请参阅我对 OP 的评论。
  • 我已编辑您的答案,并尝试回答“出于什么目的?”问题也是如此。那样可以么?随意改进。没有人回答“为了什么目的?”。
  • @Dr.Gut 我已经用我自己的解释替换了它,对不起。 :P 不过,您可以将其作为单独的答案发布。
  • @HolyBlackCat:我完全同意。我最大的希望是,你会用你自己的解释来代替它。谢谢。
【解决方案2】:

对此没有唯一的答案。

标准之外的一些东西可以被视为纯粹的增强。标准建议了其中一些增强功能(“如果 X 则取决于实现”),甚至根本没有提及(#include <windows.h>)。

对于其他事情,标准确实要求编译器标记违反标准的行为。但是标准没有谈论错误或警告。相反,它说“需要诊断”,这被理解为表示错误或警告。在其他情况下,它甚至会说“无需诊断”(NDR),这意味着编译器没有义务标记非标准代码。

因此,根据已删除的功能,它可能需要也可能不需要诊断。如果它确实需要诊断,你通常可以告诉编译器你对那个特定的诊断不感兴趣。

【讨论】:

  • 正式地说,“诊断”就是实现所说的任何内容。如果文档说! 是一个诊断,那么在每次编译(成功与否)之后简单地打印! 的编译器将符合要求。当然,没有人会使用这样的编译器。但是诊断的细节是严格的实施质量。 +1。
【解决方案3】:

是否允许编译器支持标准中删除的功能?目的是什么?

编译器可以为所欲为。 C++ 标准规定了 C++ 语言 的规则,虽然他们会咨询编译器供应商以确保其规则是可实施的,但供应商自己会做他们认为对他们和他们的用户最有利的事情。编译器有许多开发人员一直使用的非标准特性。而且我认为这些编译器中的任何默认情况下都不完全符合标准。

也就是说,如果编译器+设置允许-C++17代码或拒绝有效 C,我不会称它们为“C++17兼容” ++17 代码(由标准规定)。如果需要完全合规,大多数编译器都有可以设置的设置。


如果你想学究气,尽管 MSVC 甚至不符合 C++11 标准 due to lacking preprocessor。标准不是一切。

【讨论】:

  • 如果我们变得迂腐,由于各种错误,没有编译器是真正兼容的。 :P
  • @HolyBlackCat:即使是标准本身也有错误。甚至它还有一些不被认为是错误的功能,这让我很恼火。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
相关资源
最近更新 更多