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

Are compilers allowed to support a feature, that is removed in the standard?

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

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

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

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

Are compilers allowed to support a feature, that is removed in the standard?

标准不允许这样做。 AFAIK 一般而言,它不会对 曾经是 的语言特性进行任何特殊处理(不会将它们与 non-existent 特性分开)。

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


For what purpose?

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

如果您使用的库在其 headers 中使用了已删除的功能,但又想在您自己的代码中使用新的语言功能,这会很有用。

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


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

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

没有单一的答案。

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

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

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

Are compilers allowed to support a feature, that is removed in the standard? For what purpose?

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

就是说,如果编译器+设置允许 -C++17 代码或拒绝 valid C++17 代码(按照标准规定)。如果需要完全合规,大多数编译器都有可以设置的设置。


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