News Hacker|极客洞察

23 184 天前 phoronix.com
🤔Linux 内核拟启用 Microsoft C 扩展(-fms-extensions),引发标准与政治争议
把微软的 C 扩展放进内核,是要把内核卖给微软吗?

🎯 讨论背景

这是关于 Linux 内核是否在编译器层面允许 -fms-extensions(GCC/Clang 的 Microsoft C 扩展)的讨论,核心是如何兼容 Microsoft 头文件中出现的非标准 C 语法。评论展开了对 Unnamed Structure and Union Fields(匿名结构/联合字段)与 ISO C11 限制的技术解释,并引用了 WG14(ISO C 标准委员会)的提案理由与历史 LKML(Linux kernel mailing list)讨论记录。另有关于是否应先采用 -fplan9-extensions(Plan 9 的扩展)或分步放宽的实务性建议,以及显著的政治/信任担忧,涉及社区对微软影响力和项目主权的考量。整体讨论交织技术兼容、标准化保守性与对厂商动机的信任问题。

📌 讨论焦点

技术细节(-fms-extensions 功能)

-fms-extensions 会接受 Microsoft 头文件中出现的一些非标准 C 语法,核心是对 Unnamed Structure and Union Fields(匿名结构/联合字段)的宽松处理。与 ISO C11 不同,-fms-extensions 允许内层 struct/union 带标签或在成员声明中使用与类型同名的标识符,例如 typedef int UOW; struct ABC { UOW UOW; };,从而支持类似“伪继承”的结构嵌入和通过父类型指针访问子类型成员的技巧。评论中举例说明这种行为使得把 child 强转为 parent 并调用 parent 函数、直接访问嵌入字段变得合法和更简洁。相关讨论还引用了 GCC 文档并指出文档对这些扩展的描述相对简略,但功能影响明确。

[来源1] [来源2] [来源3]

为何未被纳入 ISO 标准(标准化争议)

C 标准化小组 WG14 曾拒绝将某些匿名成员用法纳入标准,理由是会在 C 与 C++ 之间制造不必要的语义差异:在 C++ 中内层类型名被视为对类作用域的前向引用,而不是匿名成员定义,这会导致两种语言行为不一致。提案文档还指出这类用法在实际应用中并不广泛,因此没有足够理由引入可能产生兼容性问题的特性。评论中引用了这份提案并把标准化小组的保守性作为内核是否允许扩展时必须权衡的技术与规范性理由。历史上也有多次在 LKML 上的讨论(例如 2007、2018)证明这是一个长期存在的争议点。

[来源1] [来源2] [来源3] [来源4]

替代方案与分步启用(-fplan9-extensions vs -fms-extensions)

部分评论建议采用或先引入 -fplan9-extensions 作为替代,因为它包含比 -fms-extensions 更多的扩展,而且并非两者的别名。历史记录显示 -fplan9-extensions 在早期被认为在当时的 GCC 中实现得太新(如 gcc-4.6 时代),在 2018 年的 LKML 讨论里因此未被采纳;因此有人主张采取分步策略:先允许范围较小的 -fms-extensions,之后再考虑更广泛的 plan9 扩展。还有评论认为直接允许 -fplan9-extensions 会消除大部分基于“来自微软”的反对声音,但也有人担心一次性增大兼容面会带来更多风险。

[来源1] [来源2] [来源3]

政治与信任问题(对微软的担忧)

一些评论把技术决策上升为政治与信任问题,直接引用“embrace, extend and takeover”等表述,提醒社区对微软主导的或特有扩展保持警惕。有观点认为在内核层允许微软特有行为等于向厂商妥协,呼吁小心谨慎;也有人指出反对声中存在对厂商来源的偏见,称部分反对是基于对微软的不信任而非纯技术理由。因此讨论不仅是兼容性和标准化的权衡,同时也涉及社区对外部公司影响力与项目主权的担忧。

[来源1] [来源2] [来源3]

📚 术语解释

-fms-extensions: GCC/Clang 的编译选项,用以启用 Microsoft C 的非标准扩展(例如对匿名结构/联合字段的宽松处理及 Microsoft 头文件常用语法),以提高与微软代码的兼容性。

-fplan9-extensions: GCC 的编译选项,启用 Plan 9 特定的 C 扩展,功能比 -fms-extensions 更广且并非别名;历史上在内核社区被讨论但因实现成熟度和兼容性而被谨慎对待。

Unnamed Structure and Union Fields: 即匿名结构/联合字段。ISO C11 允许内层匿名 struct/union(无需标签)并直接访问其成员,但不允许内层类型带标签;微软扩展放宽该限制以支持带标签的内层类型和伪继承式嵌入。