C++26 草案被否,二十八年来头一回

0 阅读3分钟

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