ms-extensions 标志对 gcc 有什么作用?

What does the ms-extensions flag do exactly with gcc?

GCC 有一个标志 -fms-extensions

这个标志到底有什么作用?为什么它有时默认打开,为什么它存在?

根据 gcc 9.1.0 源代码(grepped for flag_ms_extensions),效果是:

  • (C) 允许 Microsoft 版本的匿名联合和结构。这包括对 C11 anonymous unions and structs as well as Microsoft-specific flavours 的支持,包括完全省略大括号成员列表,以及将成员放置在 parent 命名空间中,即使 struct/union 具有标识符也是如此。
  • (C++) 允许 class 成员与其类型同名(例如 using foo = int; struct A { foo foo; })。 ms-extensions 禁用时,行为是在 C 中接受此代码(在合法的地方);或 extern "C" 块,除非给出 -pedantic 标志。此错误消息是 declaration of NAME changes meaning of NAME.
  • (C++) 允许 隐式 int;现在允许任何会产生诊断 ISO C++ forbids declaration of NAME with no type 的情况,并假定 int 为类型。示例:const *p;const f();.
  • (C++) 允许从 qualified-id 命名的 non-static 成员函数隐式转换为 pointer-to-member。在 ISO C++ 中,需要 & 运算符来执行该转换。
  • (C++) 允许 &f 形成一个 pointer-to-member,如果 f(一个 unqualified-id)在该上下文中命名一个 non-overloaded 成员函数. ISO C++ 要求使用 class 名称进行显式限定。

如果目标 ABI 是 Microsoft ABI,则该标志默认打开。可以通过手动指定 -fno-ms-extensions.

来禁用它

这背后的基本原理是一个更棘手的问题。 documentation has 说:

Accept some non-standard constructs used in Microsoft header files.

Disable Wpedantic warnings about constructs used in MFC.

所以我认为基本原理是允许 g++ 构建 MFC 依赖于 MSVC non-standard 代码的应用程序 vendor-supplied headers.

我不确定它在 2019 年的相关性如何,我认为可以为 gcc 默认关闭此标志提供一个很好的案例。 (如果用户想要构建旧的 MFC 应用程序,他们可以随时指定它)。

例如 MSVC 19.xx(迄今为止的最新版本)在其默认模式下不再允许最后三个要点。 (它仍然允许 foo foo; 即使有 /Za 标志)。