Professional Documents
Culture Documents
03
03
C++ 标准委员会
委员会成员都是志愿者,也没有带薪的秘书处,虽然许多委员确实以其工作组织的代表身份出现。在每次会议上,
都会有人自豪地声称就代表“自己”。也就是说,他们没有得到赞助,只代表自己。有些人换工作后,就会代表
新组织,这种情况并不少见。许多人以“参加 C++ 标准委员会”作为接受新工作的条件。有人加入了委员会来
学习 C++,有人则把“C++ 委员会成员”当作资格来引用(并非一定是真的)。
有些人仅参加过几次会议,不那么经常。另一方面,也有人一直参加了大多数会议,数十年没有间断。一开始时,
还有现在,我们一年开三次会。在 1998 年标准之后的几年里,我们一年只开两次会。目前,除了面对面的会议,
还有很多的电话会议进行补充,以及天天都有的大量电子邮件。
在这里,我会描述
- 标准的作用([§3.1](#31-标准))
- 委员会的组织([§3.2](#32-组织))
- 委员会的结构对 C++ 设计的影响([§3.3](#33-对设计的影响))
## 3.1 标准
标准委员会的目的是编写标准。制定标准的一个官方理由是“**促进贸易,特别是减少国际贸易的技术壁垒和人
为障碍**”,及“**提供实现经济、效率和互操作性的框架**”。标准是规范,不是实现。它的目的是保持多个实
现一致,并确定“一致性”在一个必须能够有效利用各种不同底层硬件的世界里到底意味着什么。许多程序员在
理解这一点上存在问题。他们要么认为当前的编译器就是语言的定义,要么难以理解为什么很难在许多不同的、
通常是竞争性的组织之间达成 100% 的协议。在 1990 年代,委员会考虑过制定形式规约(formal
specification),但咨询过世界一流的专家后得出结论,规约技术的进展和成员的水平都还达不到制定 C++
形式规约的程度。当然,也考虑过参考实现,但语言的复杂度,特别是与硬件使用和优化相关的问题,已经挫败
了这种想法。如果有参考实现,它会太复杂,也会代价过大。要么就得把它简化到一种对最困难的问题没有帮助
的程度,但这样的困难问题正是最需要参考实现的场合。再有,当 N 个彼此竞争的实现团队记录他们的决策、运
行广泛的合规性测试并讨论它们的不同之处时,会有些意外收获;如果已经有了个复杂的参考实现,就可能掩盖
掉这样的意外收获。对于 C++,从前端实现来说(Clang、EDG、GCC 和微软)N 至少为 4,至于后端,N 少
说有十几个。
无论好坏,C++ 社区选择了“半组织”的混乱,里面有一个很大的委员会加上多个编译器、工具及库的供应者。
我们没有用统一所有权或独裁者模式。
## 3.2 组织
对于 C++17 和 C++ 20 的工作,每次面对面的 WG21 会议有多达 250 人出席,而总成员人数约为出席人数
的两倍。此外,加拿大、芬兰、法国、德国、俄罗斯、西班牙、英国、美国等十几个国家都有国家标准委员会以
及 C++ 标准技术联盟的付费支持成员。成员代表了一百多个组织。为了让大家有所了解,在此列举部分成员所
属组织:苹果、Bloomberg、欧洲核子研究中心、Codeplay、EDG(Edison Design
Group)、Facebook、谷歌、IBM、英特尔、微软、摩根士丹利、英伟达、Qt、高通、红帽、Ripple、美国
Sandia 国家实验室、拉珀斯维尔应用科技大学(HSR)和马德里卡洛斯三世大学。编译器供应者、硬件供应者、
金融、游戏、库供应者、平台供应者、国家实验室(物理)等都有坚实的代表。早期 C++ 中突出的电信业者的
身影已经减少,而过去极少的大学的身影似乎在增加。
显然,如此庞大的组织和个人组成的群体代表着千差万别的兴趣和技术背景,需要一个组织结构来运作。会议是
围绕工作组(WG)和研究组(SG)进行组织的。2019 年的夏天,我们已经有了这样一些分组:
研究组探索新领域并设计可能的标准化:
工作组可持续十年以上,成员变化也很少。研究组则聚散自由,可能因兴趣使然,或者因为工作已经完成并提交
给工作组进行最后的处理。例如,四个最重要的研究组已宣告胜利完成并解散:
**SG4 网络**,目前处于休眠状态,因为其结果正在等待被合并到标准([§8.8.1](08.md#881-网络库))中。
另一个研究组 **SG11 数据库**,因缺乏共识和缺乏足够数量的志愿者完成工作而解散。
某些研究组会产出技术规范(TS),这些技术规范可能是具有重要意义的文件,也以标准本身的风格写就。它们
具有一定的官方(ISO)地位,但不能提供国际标准(IS)所具有的长期稳定性。并发研究组(SG1)自 2006
年以来一直活跃,大部分时间由 Hans-J. Boehm(谷歌,之前代表过惠普实验室和 SGI)领导,它的地位已经
接近 WG 了。
ISO 只需要也只认可三名正式官员:
- **召集人**——担任工作组主席,制定工作组会议时间表(召开会议),任命研究组,并向更高级别的
ISO(SC22、JTC1 和 ITTF)负责——Herb Sutter(微软),自 2002 年以来一直担任该职位的工作,除
2008–2009 年期间是由 P.J. Plauger(Dinkumware)担任。
- **项目编辑**——最终负责将委员会批准的更改应用于标准的工作草案——Richard Smith(谷歌);Pete
Becker(Dinkumware)负责 C++11;Stefanus Du Toit(Intel)负责 C++14。
- **书记**——负责记录和分发 WG21 会议的会议纪要——Nina Ranns(Edison Design Group,之前代表
Symantec)。
各个国家的标准委员会有各自自己的官员和章程。
在 WG 和 SG 里,每个出席者都可以投一票。委员会全体会议的正式投票则是每个到会的组织一票(这样,大型
组织就不会有多票),再加上国家标准机构的票数。“技术性投票”和国家机构投票必须一致才算达成共识。
## 3.3 对设计的影响
此外,委员会的管理结构非常薄弱,甚至缺乏最基本的管理工具:
当关注由一个庞大的委员会引起的问题时,也请记住,这些问题本质是一种有钱人的烦恼:C++ 的标准化流程由
数百位各种不同背景的热心人士所驱动,他们的经验各不相同,但都满怀理想主义。
委员会应起到过滤作用,也就是说,把坏提案挡在标准之外,同时,还要提升最后通过的提案的品质。委员会的
存在,是要鼓励大家提出建议,并主动提供帮助。然而,并没有正式的提案征求流程。
委员会中的教育工作者相对较少。这可能是个问题,因为委员会(理所当然地)高度重视“易于学习”,但是委
员们对其含义有着非常不同的理念(经常会意见强烈)。这往往使关于“简单性”和“易用性”的讨论变得混乱。
- **延迟**:多阶段的流程为延迟、阻止提案和提案变化提供了很多机会。常常出现几十名委员坚持要满足他们
的要求的情况,往往是通过阐释、扩展和寻找特例的方式。一个人眼中的过度延迟在另一个人看来却是尽职尽力。
例如:概念(当前方案为 6 年([§6](06.md#6-概念)))、契约(从开始到失败花了 6 年
([§9.6.1](09.md#961-契约)))、网络(15 年,仍在进行中([§8.8.1](08.md#881-网络库)))和
constexpr(5 年([§4.2.7](04.md#427-constexpr-函数)))。甚至 `nullptr` 被接受也花费了三
年时间([§4.2.6](04.md#426-nullptr))。
- **孤立特性**:大多数委员会成员喜欢特性的添加。另一方面,他们(非常合理地)深刻地担心破坏现有代码
的可能性。这给了**孤立特性**系统性的优势,孤立特性是不影响语言和标准库其余部分的小提案。这样的小提
案很少会对语言的使用产生重大影响,但却会增加学习和实现的复杂性。而且,到头来,它们往往还是会和其他
特性发生令人惊讶的交互。
例如:大多数在本语言演化总结中不值得提及的特性。结构化绑定([§8.2](08.md#82-结构化绑定))和
运算符 `<=>`([§8.8.4](08.md#884-缺省比较))都需要多次会议去完善。
- **后来者居上**:有时经过多年的工作之后,提案已接近投票表决,一些一向未曾关注提案的委员此时进入讨
论并提供了替代提案。这样的提案可能与原始提案有戏剧性的差异,或者只是一系列小的请求。这往往导致延迟、
混乱、甚至有时是争执。这种时候,已经议定的问题又重被激活,而未经尝试(通常也未实现)的新想法和多年
工作的成果获得了接近相等的权重。对老提案而言,瑕疵已经被发现过了,相应的技术折中也已经完成。人们很
容易想象新事物的好处而忘记意外后果定律:**意外后果总是会出现的**。新的和相对未经审查的总是看起来比
老的更好。这使得较早提案的拥护者变得具有防御性,从而分散了进一步完善“老提案”的精力。在这里“老”
可能只是几年,或者就像概念([§6](06.md#6-概念))那样十几年。有时,接受未经尝试的后期变更(所谓改
进)是为了安抚反对派;这经常导致意外的后果。后期加入讨论的人们,通常不会认为有“冲刺的必要”,而是
自然地希望他们自己的想法得到认真考虑(而通常并没有认真考虑老提案的细节和理由)。这就可能会与已经在
老提案上投入多年工作的人们产生摩擦。
例子:结构化绑定(语法更改,对位域的新增支持,笨拙的 `get()`([§8.2](08.md#82-结构化绑
定)))、概念([§6](06.md#6-概念))。数字分隔符([§5.1](05.md#51-数字分隔符))、点运算符
([§8.8.2](08.md#882-点运算符))、模块([§9.3.1](09.md#931-模块))、协程([§9.3.2]
(09.md#932-协程))、契约([§9.6.1](09.md#961-契约))。
- **热情总青睐新事物**:唤起对新事物的热情比反对它们容易。每个提案都是为某人解决某事,支持者愿意花
大量时间展现其价值。而要反对它们,有人就不得不说像这样的话:
- “不,这个问题不是那么重要。”
- “不,这种解决方案有缺陷。”
- “不,你还没有充分记录解决方案。”
- “不,你还没有仔细检查替代方案。”
不管措辞怎么客气,这都让反对者看起来更像“坏人”,是他们阻碍了进步并否认支持者需求的合理性。更
糟糕的是,拥护者总是比反对者花费更多的时间来准备论文和演讲。大多数人喜欢对自己相信的事物进行建设性
的工作,而不是小心地拆除他人的工作。因此,支持者通常都很热情并且准备充分,而反对者总是显得意见含糊
而不懂细节。然而,每项新特性都有其成本:如设计、规范、实现、修订、部署和教学([§9.5](09.md#95-次
要特性))。我害怕在演化工作组度过周四下午。那时,EWG 成员经过几天的大提案工作而感到疲倦,许多老成
员(例如我)已经被拖入其他小组,参会者又急于看到有成果。这种时候,小提案就会只经受相对较少的审查而
滑入标准。
例如:条件中的显式测试([§8.7](08.md#87-条件的显式测试))、`inline` 变量([§8](08.md#8-
c17 大海迷航))、结构化绑定的后期更改([§8.2](08.md#82-结构化绑定))。
例子:出于对犯错者的保护,就不举例了。
- **实现时机不当**:在标准流程中,实现提案晚了有风险:特性出现严重缺陷、有潜在无法实现的部分、以及
缺乏使用反馈;实现早了也有风险:特性以不完整的、次优的且难以使用的形式冻结。委员会中的许多人不会投
票赞成尚未实现或以他们不信任的方式实现的提案。另一方面,许多实现者不愿意为委员会未批准的提案投入实
现资源。这是一个困难而现实的两难困境。委员会经常听到“它已经实现了吗?”的问题。通常,“它是经过设
计的吗?” 和“要如何使用?” 是更重要的问题。人们很容易在细节中迷失。我提出的走出这一困境的方法是,
就建议的方向、提案的总体范围达成一致,然后从一个相对较小子集的详细设计和实现出发,以关键用例为指导
前进。这样,我们可以相对较早地获得用户体验,并了解该特性如何与其他特性交互。这需要对这种语言应该是
什么有一个长远的看法 [Stroustrup 1993, 1994, 2007]([§1](01.md#1-前言)),([§11.2]
(11.md#112-技术上的成功)),否则语言就会沦为机会主义的零敲碎打。如果这个方法起作用,语言将从反馈
和有机增长中受益。
例子:模块([§9.3.1](09.md#931-模块))、C++ 0x 概念([§6](06.md#6-概念))和 `<=>`
([§8.8.4](08.md#884-缺省比较))。
- **特性交互**:最难处理的问题之一是特性的组合使用。一定程度上这是规范和实现的技术问题。因此,这会
占用大量委员会时间。从设计的角度来看,更难的问题是要预计新特性在整个语言的语境中如何使用,这些语境
包括其他正在考虑中的语言和库的新特性。每个特性都应设计成便于同其他特性结合使用。我担心这一点没有得
到重视。很少有提案书提供详细的讨论,而委员会里关于特性交互的讨论往往简短或混乱。其结果之一是,个别
特性趋于膨胀而只好把它孤立于语言的其余部分才能用起来。
例子:`tuple`([§4.3.4](04.md#434-tuple))和 `<=>`([§9.3.4](09.md#934-))。为
lambda 表达式([§4.3.1](04.md#431-lambda-表达式))中的动作指定专用语法的(失败)提案。
- **篇幅和分心**:千头万绪往往同时发生,没有人能全跟得上。那些尝试全部关注的人,就容易失去对真正重
要课题的关注,而把注意力分散在一些事实证明并不那么重要的课题上。如今每年有超过 500 篇委员会论文,
有些长达数十甚至数百页。与 2010 年代初相比,文献总篇幅翻了一番。我注意到,2018 年秋天的会前邮件
(新论文汇总)的字数是莎士比亚全集的三倍。
电子邮件的泛滥最让人分心,因为许多委员喜欢通过一波一波地爆发短邮件来进行技术讨论。在这样的讨论
中掉队意味着失去对问题的跟踪,其结果可能是,共识只是从几个一直能跟得上讨论的人中间浮现。
这种讨论不利于冷静而系统地权衡各种选择。有时候,它会导致不幸的特性滑入标准。有时候,它会导致不
一致的设计理念体现于语言和标准库的不同部分,进而损害了互操作性。
- **精确规范**:标准是规范,而不是实现。但是,标准是用英语编写的,因此我们做不到数学般的精度。委员
会的许多成员擅长数学,但不擅长数学的人更多,因此在规范中没办法使用数学式的写法。试图使英文文本精确
而详尽,则会让文本变得生硬又难以理解。我常常很难理解标准中对我自己提案的描述。
大多数委员是程序员,而不是设计师,因此规范有时看起来会像程序——用没有类型系统或编译器的低级语
言写成的程序。有详尽的如果、那么、否则的说明,却很少写出不变量。更糟糕的是,很多词汇继承自 C,而且
是基于程序源代码文本中的标记,因此,更高级别的概念仅被间接提出。
奇怪的是,标准库规范在结构上明显比语言规范更为正式。
- **经院主义**:当然有必要大力强调标准文本的正确性和准确性。但是,人们有时会忘记标准本身可能就是错
误的,而仅根据标准文本的论证来讨论正确性。这样一来,根据标准文本所应反映的模型和使用上的论证,反倒
可能被忽略。
- **方向**:哪些问题是真实的?重要吗?对于谁?哪些紧急?十年后,哪些解决方案仍然有意义?有些事情也
许算个问题,但这并不意味着它必须在语言里有直接的解决方案。尤其是,委员会很难记住这一点:一种语言不
可能对所有人来说都是万能的。更难以接受的是,它居然不能解决每个委员最紧急的问题 [Stroustrup
2018d]。
- **原则的不适当应用**:将一般原则应用于具体事例通常很困难。有时,我们会不与其他原则进行必要折中,
就去严格应用某项原则。折中的必要性是《设计和演化》一书 [Stroustrup 1994] 将设计原则称为“经验法
则”的原因之一。有时,似乎没有经验基础就凭空冒出来一个原则。有时,一个提案严格遵循了某一个原则,而
另一个提案则忽略它。有原则的设计很困难;它需要品味、经验以及原则。实用的语言设计不只是从第一原理出
发进行演绎的练习。通常,多种原则之间必须进行权衡。
- **倾向专家的偏见**:想象别人的问题总是困难的。委员会成员几乎都是某方面的专家。在日常工作中,他们
通常是处理最细微、最复杂问题的人。这样的问题在“外面”的数十亿行常规 C++ 代码中一般不常见,而且也
不是大多数 C++ 程序员所苦恼的问题。但是,对委员会来说,专家级的问题通常就是紧急问题,也是最容易通
过流程的问题。
- **聪明的问题**:委员会成员一般是聪明人,他们中许多人无法抵御机灵的解决方案。此外,他们也很难断定,
并非每个问题都值得解决,而拥有解决方案也并不意味着我们必须将其纳入标准。这会带来过于精巧的特性,带
来大多数程序员用不着的特性。公平起见,也需要指出,许多程序员也很聪明,有时也会以使用过分机灵的语言
和标准库特性为乐。
例子:在有些提案中,即使简单用法也需要用上严肃的模板元编程。
- **不愿妥协**:大多数委员会成员都有强烈的意见,但要在一个大型团体中达成共识需要妥协。分辨哪些妥协
无关紧要,而哪些妥协事关基本原则,有时会很困难。后一类妥协可能对语言造成破坏,应该避免。不幸的是,
当委员们坚信自己所担忧的才至关重要时,他们比起心态开放的委员就有了有关键的战术优势。有些人能做到从
整体上关注语言而不纠结于个别话题,但他们往往得向不能如此的人们屈服。而反过来,那些从不认真质疑自己
的原则或需求的人,倒往往可以向别人视为必要的技术妥协发动猛攻。取得进展需要关注整个社区,有自知之明,
并懂得适当的谦逊 [Stroustrup 2019b]。
- **缺乏优先级**:从技术的角度来看,所有问题都是平等的:不精确的规范就是不精确的规范,这一点与它未
能正确规定的内容是什么不相干。任何可能从类型系统的漏洞中混进代码的错误原则上都可能造成死亡和毁灭。
但是,现实世界中不同错误的影响可能大不相同。实际上,大多数晦涩的细节基本上没有破环性。有些人在研究
设计细节时很难记住这一点。
例子:在数字分隔符([§5.1](05.md#51-数字分隔符))上花费的时间比在范围 `for`([§4.2.2]
(04.md#422-范围-for))上花费的时间更多。
- **完美主义**:一个标准预期会被几百万人用到,并且可以稳定数十年。人们自然希望它是完美的。这会导致
特性膨胀(特性过多),尤其是导致单个特性的膨胀。程序员善于想象出问题,特性在委员会走流程的时候,委
员们会坚持要它解决掉所有想象中的问题。这会导致严重的使命偏离,并导致只有专家才会喜爱的特性。这也可
能导致特性一直无法加入标准。
例子:`.` 运算符([§8.8.2](08.md#882-点运算符))、网络库([§8.8.1](08.md#881-网络库))
和异常规约([§4.5.3](04.md#453-noexcept-规约))。
- **少数人的阻挠**:共识流程可以防止某些类型的错误,尤其是防止多数人的暴政。但是,它很容易受到个人
和小团体的阻挠。这可以是好事(避免错误),但是当它在提案流程的各个阶段一再发生,或正好在最后一刻发
生时,就会具有破坏性了。
例子:`constexpr`([§4.2.7](04.md#427-constexpr-函数))、`.` 运算符([§8.8.2]
(08.md#882-点运算符))、模块([§9.3.1](09.md#931-模块))和协程([§9.3.2](09.md#932-协
程))。
- **内聚的团体**:许多工作组和研究组都拥有稳定的核心人员群体,这些年来他们形成了内聚的技术观、共享
的词汇表和特定的运作方式。这会使“外部人员”难以交流和贡献。这也可能使设计跨越 WG 边界的特性(例如
同时具有库和语言部分的特性)变得困难。每个小组都往往会设计出适合其自身组织结构领域的内容,再次印证
了老格言,即系统的结构总是长得像创造它的组织的结构。
例子:范围 `for`([§4.2.2](04.md#422-范围-for))和可能需要更改语言的并发机制([§4.1.3]
(04.md#413-期值 future))。`any`、`optional` 和 `variant`([§8.3](08.md#83-
variantoptional-和-any))的接口差异。
从积极的一面来看,基于个人敌意或针锋相对的行为非常罕见。从这个意义上讲,委员会是非常专业的。
幸运的是,并非每个提案都受所有这些现象的影响,并且大多数其他大型项目也会遇到这类问题。但是,以其
ISO 标准所代表的 C++ 语言,整体上反映出了这些现象。它们不是新问题,但是自 C++11 起出现得越来越多。
我怀疑它们是由以下因素共同造成的
- 委员会人数增加
- 新人的涌入
- 成员的专业化(分散化)
- 成员对 C++ 历史的了解有所减少
尽管存在这些严重的问题,但标准制定流程仍屡屡成功,原因之一是很多人不断努力将负面影响降到最低。方向
组(Direction Group)的建立就是这方面的努力的一部分([§3.2](#32-组织))[Dawes et al. 2018;
Stroustrup 2018d]。另见([§11.4](11.md#114-教训))。工作组主席、笔记记录员、会议组织者和编辑
组的不懈努力是无形的,但却至关重要。例如,Jens Maurer 数十年来一直在 CWG 中做笔记,帮助提案者编
写标准文本,安排网络访问,为无法出席的成员安排电话接入,安排会议室,告知成员当地旅行的可能性,等等。
有其他方案吗?在理想的世界里,我会建议限定由一小部分(大约 5 人)的全职受信任专家委员做决定,而由大
团队完成(例如超过 350 人的委员会)完成讨论、提案、以及大部分流程。但我不认为 C++ 会发展成这样,因
为:
- 没有人喜欢放弃权力(在这种情况下是投票权)。
- 要为固定的全职专家团队保持稳定的资金投入需要非同小可的技能(而这种技能在 C++ 社区还没有出现)。
- 激进的变化不会发生在成功的时候;只有 C++ 使用量的显著下降才能促使委员会进行剧烈的组织创新(到那
时多半为时已晚)。
我不认为公司控制是可行的替代方案,因为:
- 公司期望投资回报。
- 公司的支持往往几年后就会消失。
- 公司往往选择差异化的优势,而不是惠及所有人的进步。
我也不认为完全开放的审议流程(由成千上万人投票)是可行的:
- 超过千人的投票就会失去品味。
- 大群体的成员和意见没法在几十年里保持稳定。
我从温斯顿·丘吉尔的格言中得到些许安慰,“民主是最糟糕的政府形式,除了所有那些人类一再尝试过的其他形
式”。
特别要指出,我不认为经常被建议的“仁慈的终身独裁者”模式可以规模化,而且,不管怎么说,该模型从来就
没对 C++ 适用过。
在我心目中,启动语言设计项目的理想模式是单个人或一小群密切配合的朋友。但我看不到这种方式可以规模化。
一门成熟的语言需要数十甚至数百个人来解决他们必须面对的各种问题。即使只是与相关的标准、行业组织进行
协调,也会让一个小规模、紧密配合的团体彻底应接不暇。
## 3.4 提案检查清单
- 要解决的问题是什么?将为什么样的用户提供服务?新手?专家?
- 解决方案是什么?阐明它所基于的原则。给出简单的使用案例和专家级的使用案例。
- 有哪些替代解决方案?库解决方案是否足够?为什么现有功能不够好?
- 为什么解决方案需要在标准中?
- 采用该技术存在哪些障碍?从现有的技术过渡可能需要多久?
- 已经实现了吗?在实现过程中遇到了或预期会遇到哪些问题?有用户体验吗?
- 会不会有很大的编译期开销?
- 该特性是否能融入到现有工具和编译器的框架中?
- 与变通方案相比,会有运行期开销吗?在时间上?在空间上?
- 会有兼容性问题吗?会破坏现有的代码吗?ABI 会被破坏吗?
- 新功能将如何与现有功能和其他新功能交互?
- 解决方案是否容易教授?教给谁?谁来教?
- 标准库会受到怎样的影响?
- 该提案是否会导致对未来标准进一步扩展的要求?
- 该特性在标准里如何措辞表达?
- 用户在使用新功能时可能会犯哪些错误?
- 就整个 C++ 社区的利益而言,该提案是否属于前 20 名?前 10?
- 该提案是否属于特定子社区的前三名?哪个子社区?
- 该提案是解决某一类问题的通用机制还是某个特定问题的特定解决方法?如果是针对一类问题,是哪一类问题?
- 该提案在语义、语法和命名方面是否与语言的其余部分一致?
理想的情况是,一项提案能够回答所有这些问题,甚至更多,但这种情况很少发生。特别是,在最初的提案中,
理由往往非常薄弱,因为提案者认为所处理的问题的重要性和他们建议的解决方案非常明显。然而,后续的论文、
修改、电子邮件讨论和演化组的面对面讨论通常都会涉及这些问题,但很少对各个提案进行系统的或一致的检查。
成员们倾向于关注技术细节(例如,语法、歧义、优化机会和命名),而不是重新探讨根本问题。有时,我所认
为的糟糕的提案会混进去。原因通常是提案者的极大热情加上反对者的分心、礼貌和疲惫 [Stroustrup
2019b]。