【发布时间】:2019-10-26 12:25:00
【问题描述】:
GCC 有一个标志 -fms-extensions。
这个标志到底是做什么的?为什么有时会默认开启,为什么会存在?
【问题讨论】:
GCC 有一个标志 -fms-extensions。
这个标志到底是做什么的?为什么有时会默认开启,为什么会存在?
【问题讨论】:
根据 gcc 9.1.0 源代码(grepped for flag_ms_extensions)效果是:
using foo = int; struct A { foo foo; })。在禁用 ms-extensions 的情况下,行为是在 C 中接受此代码(合法的地方);或extern "C" 块,除非给出-pedantic 标志。错误消息是declaration of NAME changes meaning of NAME。ISO C++ forbids declaration of NAME with no type 的情况,假设int 为类型。示例:const *p; 或 const f();。& 运算符是执行该转换所必需的。&f 形成一个指向成员的指针,如果f(一个非限定ID)在该上下文中命名一个非重载成员函数。 ISO C++ 要求使用类名进行明确限定。如果目标 ABI 是 Microsoft ABI,则默认情况下打开该标志。可以通过手动指定-fno-ms-extensions来禁用它。
这背后的基本原理是一个更棘手的问题。 documentationhas 说:
接受微软头文件中使用的一些非标准结构。
禁用有关 MFC 中使用的构造的 Wpedantic 警告。
所以我假设理由是允许 g++ 构建 MFC 应用程序,这些应用程序依赖于 MSVC 供应商提供的标头中的非标准代码。
我不确定这在 2019 年的相关性如何,我认为可以为 gcc 默认关闭此标志提供一个很好的案例。 (如果用户想要构建旧的 MFC 应用程序,可以随时指定它)。
例如,MSVC 19.xx(迄今为止的最新版本)在其默认模式下不再允许最后三个项目符号点。 (即使带有/Za 标志,它仍然允许foo foo;)。
【讨论】:
-ms-extensions 启用的功能不是标准的“匿名结构和联合”。标准匿名结构和联合仅允许嵌套的 tagless 结构/联合声明引入未命名字段。另一方面,此扩展允许引入未命名字段的 tagged 结构/联合声明。它还允许为此目的使用先前声明的结构/联合类型(标记或类型定义)。这与标准功能完全不同,而且功能明显更广泛。