ms-extensions是gcc的一个标志,它有什么作用?

7

GCC有一个标志-fms-extensions

这个标志具体是做什么的?为什么它有时默认开启,为什么它存在?

1个回答

9
根据gcc 9.1.0源代码(使用flag_ms_extensions搜索),其影响如下:
  • (C) 允许使用 Microsoft 版本的匿名联合和结构体。这包括支持 C11 匿名联合和结构体,以及 Microsoft 特有的变体,包括完全省略成员列表,并将成员放置在父命名空间中,即使该结构体/联合体具有标识符。
  • (C++) 允许类成员具有与其类型相同的名称(例如: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++) 允许从一个限定符 ID 指定非静态成员函数隐式转换为指向成员的指针。在 ISO C++ 中,& 运算符需要执行该转换。
  • (C++) 如果在该上下文中,f(不带限定符)命名一个非重载的成员函数,则允许 &f 形成指向成员的指针。ISO C++ 需要使用类名称进行显式限定。

如果目标ABI是Microsoft ABI,则默认开启标志。您可以通过手动指定-fno-ms-extensions来禁用它。
这背后的原因是一个更棘手的问题。文档 说明 需要说:

接受 Microsoft 头文件中使用的一些非标准结构。

禁用 MFC 中使用的结构的 Wpedantic 警告。

因此,我认为理由是允许 g++ 构建依赖于 MSVC 供应商提供的头文件中的非标准代码的 MFC 应用程序。
我不确定在2019年这是否仍然相关,我认为可以有充分的理由让gcc默认关闭此标志。(如果用户想构建旧的MFC应用程序,他们总是可以指定它)。
例如,MSVC 19.xx(迄今为止的最新版本)不再允许其默认模式下的最后三个项目。(即使使用 /Za 标志,它仍然允许 foo foo;)。

1
通过-ms-extensions启用的功能不是标准的“匿名结构体和联合体”。标准的匿名结构体和联合体只允许嵌套的无标签结构体/联合体声明引入一个未命名的字段。另一方面,这个扩展允许带标签的结构体/联合体声明引入一个未命名的字段。它还允许使用先前声明的结构体/联合体类型来实现这个目的(带标签或typedef)。这与标准功能相比非常不同,而且功能范围更广。 - AnT stands with Russia
@AnT 更新了,谢谢。如果不正确,请随时编辑。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接