1

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

让我感到困惑的是,一些编译器支持throw(T1, ..., Tn)C++17 模式(参见演示)。

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

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

或者这只是一个编译器扩展,就像void foo(int size) { char a[size]; }在 GCC 中一样,请参阅demo

4

3 回答 3

4

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

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

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


出于什么目的?

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

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

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


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

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

于 2020-08-03T12:18:08.837 回答
2

对此没有单一的答案。

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

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

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

于 2020-08-03T12:29:31.227 回答
0

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

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

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


如果您想变得迂腐,尽管 MSVC由于缺少 preprocessor甚至不符合 C++11 标准。标准不是一切。

于 2020-08-03T12:38:33.750 回答