C++26 的国际标准草案,在 10 月 23 日的国家代表团投票里没过。
这是这门语言 1998 年标准化以来,第一次走到最后一步又被退回来。
标准要走好几轮投票,前面是委员会内部的技术表决,最后一关叫 DIS,成员国代表团对着整份草案投一次票。
惯例上走到这一步已经是走过场,没人觉得它会被打回。
结果 10 月 23 日这一关没过,整份草案退回修改。
这一关通过之后还有出版流程,所以它一直是整条链上最稳的一段,此前唯一一次同类情况是 2006 年的 C++/CLI 语言规范。
卡住的地方叫契约编程,英文是 Contracts,做法是给函数写上「进来之前必须满足什么」「出去之后保证什么」,编译器可以按开关检查。
对写业务代码的人来说,它要做的事是把注释里那句「传进来的指针不能为空」变成代码的一部分,参数不合规时按编译选项处理,可以全关、只记录,或者直接中止。
写法长这样,函数参数后面直接挂条件:
int get_value(const std::vector<int>& values, std::size_t index)
pre(index < values.size())
{
return values[index];
}
下标越界的话,按编译选项处理:可以直接中止,也可以只记录一条违约信息继续往下跑。
返回值也能约,写成 post(result: result >= low && result <= high) 这样,函数体中间还能插 contract_assert 检查某一步是否成立。
要留神一点,契约不是输入校验,用户传进来的数据该判断还得自己判断。
对写库的人来说更有用,条件写在函数签名上,编译器知道哪些判断永远成立,运行时就少做一层检查。
麻烦也在这儿,检查开得越严,优化空间越小,两个目标互相拉扯,方案才一路做到这么复杂。
这个特性 2020 年就成立了专门研究组,做了四五年,2026 年 3 月委员会通过整份草案时,它是包含在里面的。
所以这次不是技术方案临门被否,是政治家一层的投票把它拦下来了。
国际标准是一份完整文件,投一次票,不拆开单项表决。
被否的是整份草案,附带的静态反射、并发执行框架,还有上百个没人有意见的小改进,全部跟着一起等。
反对意见也有正式文件。
三位委员会成员写过一份叫《Contract concerns》的论文,逐条列了对这个方案的不放心。
接下来有两条路。
要么改一改契约的细节重新投票,要么干脆把这个特性拿掉。
不管走哪条,反射和并发框架都得继续等,C++26 的时间表也要顺延。
这门语言不会因此死掉,编译器厂商照旧发版本,存量代码一行都不用改。
只是标准没定稿之前,谁也不能对外宣称自己完整支持 C++26,宣传页上的版本号只能继续挂着。
代价是,等了十几年的反射继续等,「让 C++ 变安全」这件事往后推了至少一个版本周期。
同期 Rust 那边不需要投票,一个版本一个版本地往前走。
对正在选型的人来说,这就是个新理由。
Hacker News 上的讨论:https://news.ycombinator.com/item?id=50360164。
你手上还有多少 C++ 项目,欢迎在评论区说说。
关于我:
- 农村程序员(
2020年回农村,至今未出村) - 独立开发者(
致力于开发 1000 个小产品) - 技术观察者(
分享编程技术,行业资讯等) - 前端之虎陈随易(
自封的) - 我的官网是:
https://yicode.tech