内容提要
C++26标准草案首次未获各国标准机构投票通过,争议集中在“Contracts”特性。该特性以标准化运行时检查替代assert,但设计复杂:虚拟函数契约被删除、与constexpr及内联的交互不明确、编译选项可能导致契约被忽略,甚至因未定义行为被编译器消除。多国曾提前反对,委员会未采纳,最终投票未达三分之二赞成、反对不超四分之一的门槛。作者认为这暴露了C++治理流程的深层问题。
延伸解读
投票失败的双重门槛
C++26草案未通过并非简单多数反对,而是同时未达到两项硬性要求:参与投票的P成员中赞成票需至少三分之二,本次仅60%;所有投票成员中反对票需不超过四分之一,本次达41%。另有12个国家弃权,部分因无法形成统一立场。这说明反对意见不仅集中,而且分布广泛,远超例行公事式的否决。
Contracts争议的技术根源
争议核心Contracts旨在以标准运行时检查替代assert,但设计存在多处模糊:虚拟函数契约已被删除,与constexpr及内联的交互不明确,编译选项可让契约被忽略,甚至因未定义行为被编译器消除。更关键的是,跨翻译单元链接时无法保证检查一定执行。一个本应提升安全性的特性,却无法承诺其检查必然生效,这动摇了支持者的信任基础。
国家机构反馈被忽视的教训
文章指出,多国国家机构在投票前已通过评论明确反对现行Contracts方案,涉及瑞典、西班牙、美国、法国等多国,要求解决安全性、不可忽略性及标准库硬化耦合等问题,但委员会未采纳。作者认为,这并非单纯游说结果,而是流程长期忽视早期反馈,最终在正式投票中集中爆发。这提示标准制定中及时回应反对意见比事后补救更重要。
发布列车模式下的高风险博弈
C++每三年发布一版标准,若Contracts错过C++26,需再等三年,且可能因反复争论而彻底搁浅。支持方因此采取强硬策略,寻求在不修改契约内容的前提下再次投票,实质是赌对方先让步。作者判断,即便各方有意妥协,ISO投票与会议流程缓慢,僵局可能持续一年以上。这暴露了发布周期与治理效率之间的深层矛盾。
Q&A
C++26标准草案为什么没有通过各国标准机构的投票?
主要争议集中在“Contracts”特性上。该特性设计复杂,存在虚拟函数契约被删除、与constexpr及内联交互不明确、编译选项可能导致契约被忽略等问题。多国曾提前反对,但委员会未采纳,最终投票未达到三分之二赞成且反对不超过四分之一的门槛。
C++中的Contracts特性是什么?它有什么作用?
Contracts是C++26提案中的新关键字,用于替代assert宏,提供标准化的运行时检查。它允许在函数上添加前置和后置条件,确保参数和返回值满足特定条件,例如检查索引是否在有效范围内。
Contracts特性在设计上存在哪些具体问题?
问题包括:虚拟函数的契约被移除;与constexpr和内联的交互不明确;编译选项可以启用或禁用契约检查,导致链接时可能忽略检查;契约谓词中的代码可能因未定义行为被编译器消除;甚至无法保证检查始终执行。
各国标准机构对Contracts提出了哪些反对意见?委员会如何回应?
多个国家(如瑞典、西班牙、美国、法国等)提出反对意见,要求不按当前形式发布Contracts、解决安全问题、确保契约不可忽略、修复const问题,并希望标准库硬化不依赖Contracts。但委员会拒绝了这些意见,仅做了微小让步。
这次投票失败对C++社区和标准制定流程意味着什么?
这是C++历史上首次标准草案未获国家机构通过,暴露了C++治理流程的深层问题,如委员会忽视国家机构反馈、流程缓慢且“全有或全无”。失败可能导致Contracts特性被推迟或放弃,并影响C++26的发布。
C++标准通常多久发布一次?如果Contracts这次没进入标准会怎样?
C++标准每三年发布一次。如果Contracts未能在本次进入C++26,可能需要再等三年,期间会面临无休止的争论和修改,部分贡献者可能退出,导致Contracts特性夭折。