C++20完成了!
C++20,近十年来最具影响力的C++版本,完成了!
原文:https://www.reddit.com/r/cpp/comments/f47x4o/202002_prague_iso_c_committee_trip_report_c20_is/
在Prague举行的ISO C++委员会议,由Avast主持,完成了C++20草稿,并投票将草稿国际标准(Draft International Standard,DIS)送出以进行最终确认和发布。从程序上说,DIS可能被拒绝,但是鉴于我们的过程和流程,不太可能发生这种事情。这意味着C++20已经完成,并且在几个月后标准将正式发布。
在此次会议中,也做了C++23的计划,将模块化标准库提高了优先级,库将支持协程(coroutines),执行器(executors)和网络(networking)。
非常感谢每一位为C++20诞生作出贡献的人 - 提案作者,会议记录者,实现者,以及所有相关的人。
这是有史以来最大的一次C++委员会议——252人参与!我们慷慨的主办方,Avast,非常棒地主办了会议,还为每位参与者组织了一场迷人的晚间集体活动。
本周,我们对C++20草稿做了以下修改和增加:
- 改进’module’和’import’的上下文敏感识别,可使得非编译器类工具更加容易地使用,比如构建系统决定构建依赖。
- 增加几个新的rangified算法。
- 增加
ranges::ssize
。 - 重新定义了module接口中’static’和’inline’的含义(P1779和P1815)。
- 解决了很多未解决的语言核心和库的问题,并做了很多语言规格上后续的改进。
C++20有以下值得注意的特性:
- Module。
- Coroutines。
- Concepts。
- Ranges。
constexpr
化:constinit
,consteval
,std::is_constant_evaluated
,constexpr
分配,constexpr std::vector
,constexpr std::string
,constexpr union
,constexpr try
和catch
,constexpr dynamic_cast
和typeid
。std::format("For C++{}",20)
。operator<=>
。- Feature test macros。
std::span
。- Synchronized output。
std::source_location
。std::atomic_ref
。std::atomic::wait
,std::atomic::notify
,std::latch
,std::barrier
,std::counting_semaphore
,等等。std::jthread
和std::stop_*
。
ABI讨论
本周语言演进和库演进组的一次联合会议中,我们有一场非常重要的关于ABI稳定性及C++中的优先级的讨论。
尽管我们对于研究未来ABI如何演进有非常强烈的兴趣,这次我们并不追求将C++23做成干净的ABI不兼容的发布。然而,我们确定鼓励作者们应该在单独的文件中进行仔细考虑,即使这将导致ABI不兼容。委员会中的很多人对于“如果能在性能上获得巨大收益时可以考虑破坏ABI兼容”表示有兴趣。
“有多少C++开发者会用它去换灯泡?”——@tvaneerd
“没有人:换灯泡就是破坏ABI兼容。”——@LouisDionne
语言进度
演进工作组孵化器(EWGI)进度
演进工作组孵化器在Prague开了三天会,看了C++23的22份文件并给出反馈。其中10份文件转发给了演进组,可能需要一些修改。值得注意的有:
一些文件收到了很多反馈,会返给孵化器,希望是在Varna举行:
- 管线重写操作符
- 统一模板参数
- 部分可修改的lambda捕获对象
- C++要支持即时编译
- 移动 = 按位拷贝
值得注意的是,提案的阶段性语言设施尚未获得共识以便继续进行。有一个重要问题被指出的是,在concepts和modules世界中,我们实际上无法进行任何语言更改,而这可能会改变一组类型的concepts的满意度。 如果一个TU(译注:tranlate unit?)认为C<T>
为真,而另一个TU在以后的某个时期认为C<T>
为假,则很容易导致违反ODR。本文中许多提案的更改都与该问题不符。但是,我们有兴趣解决问题,因此欢迎提供其他方法。
演进工作组(EWG)进度
EWG的首要任务是再次确定国家对C++20的最终意见。 完成之后,我们开始查看C++23的文件。我们总共看了36份文件。
笔记文件:
- 我们采纳了C++ IS进度规划。
- 我们采纳了C++23计划。
- 我们采纳了有关渐进式提案的流程,以确保我们减少犯错的机会
- 我们同意继续开展“未定义行为”小组的工作,以记录未来的“核心未定义或未指定行为”。他们正在记录C++现在包含的所有语言未定义行为,并且我们同意记录并证明今后所有新的语言未定义行为。
我们将3份文件标记为为C++23初步准备就绪:
如果这些文件没有任何问题,他们将在下一次会议上进入语言核心工作组。
我们继续审阅了模式匹配。这是我们今后的首要任务之一。随着我们探索设计空间并弄清所有极端情况应该如何工作,情况看起来越来越好。当前一个大讨论点是当没有匹配发生时会发生什么,以及我们是否应该要求详尽无遗。围绕表达式与语句形式进行了探索。我们正在寻找实施经验来证明设计。
我们真的很喜欢推演这一[提案](https://wg21.link/P0847),它消除了与const
和non-const
,&
和&&
成员函数重载相关的样板。它仍然需要措辞和实现经验,但是具有强大的支持。
我们将继续讨论浮点固定布局类型和扩展浮点类型,它们要求IEEE 754支持新的C++ float16_t
,float32_t
,float64_t
,并增加对bfloat16_t
的支持。
std::embed允许从文件嵌入字符串,正在取得良好的进展。
与Unicode组合作,命名通用字符转义得到了强有力的支持。
审阅了if consteval。我们不确定这是否是正确的解决方案,但是我们有兴趣解决这一通用领域的问题。
我们看到了一篇有关删除变量模板的非常可爱的文件,并决定扩展其范围,以便可以用该语言将更多内容标记为= delete
。这将使C++更加常规化,并减少对棘手问题的仅专家解决方案的需求。
核心工作组(CWG)进度
CWG的首要任务是完成对C++20的国家机构意见的处理。CWG本周剩余的大部分时间都花在研究文件和改进C++20新特性的详细规范。
我们完成了对四份微调module语义的文件的回顾:
- 我们阐明了module接口中静态(和未命名的名字空间)的含义:此类实体现在保留在内部,无法在module的接口/ABI中公开。在非module编译中,我们不赞成使用外部链接实体中的内部链接实体。 (这些情况通常会导致违反“一个定义规则”。)
- 我们阐明了
inline
在module接口中的含义:目的是,未显式声明为inline
的函数体不属于module ABI的一部分,即使这些函数体出现在module接口中也是如此。为了使module作者可以更好地控制其ABI,module接口中的类主体中定义的成员函数不再隐式inline
。 - 我们对
module
和import
关键字的上下文相关识别进行了调整,以避免更改使用这些标识符的更多现有代码的含义,并使扫描工具更直接地无需完全预处理即可识别这些声明。 - 我们改进了老式头文件(特别是C头文件)中未命名枚举的向后兼容性。如果可以通过import以多种不同方式访问这些未命名的枚举,则可以在头文件中正确合并这些枚举。
- 我们最终确定了一些微妙的概念规则:固定了
require
表达式的语法陷阱,并允许缓存concept值,这在某些情况下已被证明可以显著提高性能。 - 我们同意(追溯地,通过缺陷报告过程)将指针的bool值初始化视为位宽变窄,从而提高了语言安全性。
- 我们添加了将比较函数默认在其类之外的权限,只要比较函数是该类的成员或友元,就可以保持一致性并允许默认的比较函数非内联。
库进度
库演进工作组孵化器(LEWGI)进度
LEWGI这个星期开了三天半会议,审阅了22份文件。 在与数字组的联合会议上,我们本周的大部分工作是针对各种数字提案。 许多工作可能最终会进入提案的《数字技术规范》,我们正在努力定义其范围和目标。我们还花了很多时间在即将到来的《并发技术规范版本2》的现代I/O和并发数据结构上工作。
LEWGI研究了以下提案,其中包括:
- 数字:
- 并发
- 低级文件I/O
- 收窄转换
- 随机数
库演进工作组(LEWG)进度
在处理了剩下的少数国家机构意见以解决C++20问题之后,LEWG致力于制定有关标准库设计标准的一般策略决策。例如,我们正式将标准库中概念名称的准则编纂为代码,并澄清了SD-8,该文件列出了我们为用户提供的兼容性保证。然后,我们开始研究C++23库提案。
在会议召开之前的几周以及会议本身中,移出的对象不一定是有效的,因而引起了许多内部讨论。尽管并未采用本文中概述的确切解决方案,但我们仍在围绕算法进行更严格的措辞,以说明对在算法执行过程中暂时处于移出状态的对象执行的操作。
最大的C++23新闻:LEWG与SG1的并发专家花了一整天的时间来审阅执行器的提案——我们喜欢这个方向!这是巨大的一个步骤,它将支持网络,音频,协程库支持等。
审阅的其他C ++ 23提案包括
- 新的status_code工具
- 容器和分配器可以交流实际分配大小的能力
std::stack
和std::queue
的迭代器范围构造函数
我们还决定弃用std::string
的接受使用char
为参数的赋值运算符(LWG待定)。
库工作组(LWG)进度
主要目标是完成对NB注释的处理,并以C++20为基础重建Library Fundamentals TS。我们实现了这两个目标。
我们查看了所有48个仍未关闭的库相关的NB评论,并对其进行了回复。有些被C++20接受。有些需要修改后才被C ++ 20接受。对于某些人来说,我们认同该问题,但认为对于C++20而言进行修正风险太大,因此在C ++23中创建了一个问题以供思考。有很多回复是“对修改没有共识”,这可能意味着很多事情从“这不是一个真正的问题”变成“这个问题不值得解决”。
最后的授权文件已经过审阅和批准。现在,应清理所有标准库,以使用最新的库措辞准则,例如使用“授权”和“约束”子句,而不是“要求”子句。
花了一些时间浏览LWG未解决问题列表。我们处理了所有未解决的P1问题(“必须在C++20中修正”)。许多开放的P2问题与新的C++20特性有关的已得到解决,我们想在发布之前修复错误。
这是Marshall Clow作为LWG主席的最后一次会议。他在会议上受到全体起立鼓掌的欢迎。
并发与并行研究组(SG1)进度
SG1本周将重点放在C++23上,主要关注驱动执行器,这是我们路线图上主要的计划中的特性之一。 执行器是一项基础技术,我们将在其之上构建各种现代异步设施,因此,在C++23周期的早期将其置于标准中非常重要。
在本次会议上,LEWG批准了执行器的设计,并要求作者以完整的规范和措词修改后返回,以便在下次会议上进行审阅。
SG1审阅并批准了对发送器/接收器概念设计的改进。此修改统一了协程和发送器/接收器的生存期模型,并使我们能够静态消除对多种异步算法的堆分配的需求。
展望未来,SG1将开始研究基于执行器的提案,例如并发算法,并行算法工作,网络,异步I/O等。
网络研究组(SG4)进度
SG4开始处理有关networking TS的审阅反馈,以使其现代化以便包含在C++23中。SG4还审阅了将低级I/O与高级异步抽象统一的提案,并向作者提供了反馈。
数字研究组(SG6)进度
数字组会议在本周一进行,还跟LEWGI在周二和周四联合会议,跟SG19在周五联合会议。
我们审阅了有关多个主题的文件,包括:
编译期编程研究组(SG7)进度
Circle是C++的一个分支,可实现任意的编译期执行(例如,编译期std::cout
),并结合反射功能以实现强大的元编程。 SG7对此感兴趣,并考虑复制其中的一部分。但是,引起了对安全性和可用性问题的关注,因此拒绝了在编译期执行任意代码的能力。
除此之外,我们还继续在C++反射方面取得进展,包括反射关键字的命名和实现对函数参数进行延迟评估的潜力。
我们还研究了JIT提案,并请作者尝试将设计与当前的反射提案统一起来。
未定义行为研究组(SG12)/漏洞工作组(WG23)进度
我们着手列举所有未定义和未指定的行为。 我们已经决定,即将发布的添加了新的未定义或未指定行为的文件需要包括基本原理和示例。
SG12还与MISRA标准合作,共同开发嵌入式系统中的编程标准,以帮助他们更新有关新C++修订版的指南。
人类机器接口与输入/输出研究组(SG13)进度
SG13第13研究组简要介绍了Ben Smith在2019年CppCon主题演讲中的摘录(从1:05:00开始)。
我们看了《2D图形简介》,并鼓励探索可分离颜色提案的工作。
最后,我们研究了音频I/O软件的使用场景。我们在发布会议邮件的截止日期之前还有两周的时间收集其他使用场景,然后将征询WG21和更广泛的C++社区的反馈。
工具研究组(SG15)进度
工具研究组本周开会,继续开展有关Module生态技术报告的工作。目前,针对技术报告的三份文件已经相当成熟,因此我们指示这些文件的作者们共同努力为Varna会议创建技术报告的初稿。这些文件是:
该草案将为我们提供一个共同的工具,以开始敲定技术报告的细节,并为人们撰写文件的目标。
Unicode与文本(Text)研究组(SG16)进度
本周我们最有趣的话题涉及运行期字符集和编译期编程的交互。 提案的std::embed
和反射功能需要在编译时对字符串进行评估,这在翻译阶段7进行。这是在翻译阶段5之后的,在此阶段,字符和字符串文字被转换为运行期字符集。 这些功能需要与文件名或编译器的内部符号表进行交互。 在目标运行期字符集与编译器的主机系统或内部编码不兼容的交叉编译方案中,会发生有趣的事情。与其他许多情况一样,我们在UTF-8中找到了答案,并将提案这些功能仅在UTF-8中运行。
我们把命名通用字符转义符和使用了Unicode Standard Annex31的C++标识符语法转发给了EWG。EWG本周看了这两份文件,并有望在今年晚些时候的会议上批准进入C++23。
我们把《命名文本编码以解密》转发给了LEWG。
由于严格的ABI限制,我们拒绝了转发增强std::regex
的文件以更好地支持Unicode。 std::regex
设计向ABI公开了实现的许多内部细节,实现者表示他们无法进行任何重大更改。考虑到std::regex
的当前状态,我们无法修复其接口或已知的性能问题,因此许多志愿者同意在以后的会议上提出弃用std::regex
的文件。
机器学习(Machine Learning)研究组(SG19)进度
SG19会议开了一整天,半天和SG14(低延迟)一起,半天和SG6(数字)一起。
从ML角度提供了有关简单统计功能的重要反馈,尤其是在处理缺失的数据,非数字数据以及各种潜在的性能问题方面。
有一个很好的“P1708的评论:简单的统计函数”的演示文稿,其中介绍了针对常用统计方法的Python,R,SAS和Matlab分析。
图形库的文件引起了很大的反响,也进行了讨论,并将继续进行。
另外,在C++的差异化编程中讨论了对C++的差异化编程的支持,这对于良好集成的机器学习反向传播支持非常重要。
独立式库向前迈出了几步,提出了一些有趣的提案,包括独立式语言:可选的::operator new
。
最大的决策之一是针对嵌入式系统的低成本确定性C++异常,它获得了巨大的反响。 我们可能会听到更多有关它的信息!
契约(Contracts)研究组(SG21)进度
在一场半天的会议中,我们讨论了之前的提案中争论的主要点,就是“假设”和“断言”的关系,口语化和技术解释。我们还讨论了什么时候一个隐含了另一个,以及未来的设施应该支持什么组合。
C++发布规划
主要C++特性开发状态
注意:本计划不是承诺。这是推测的,不确定的。最新的计划请查阅P1000
- IS = 国际标准(International Standard)。C++编程语言。 C++11,C++14,C++17,等等。
- TS = 技术规格(Technical Specification)。某些但不是所有实现具有的”特性分支“。Coroutines TS v1, Modules TS v1,等等。
- CD = 委员会草稿(Committee Draft)。IS/TS草稿,用于发给国家标准组织进行审阅和反馈(“beta测试”)。
特性 | 状态 | 依赖于 | 当前目标 (保守估计) | 当前目标 (乐观估计) |
---|---|---|---|---|
Concepts | Concepts TS v1 已发布且合并入C++20 | C++20 | C++20 | |
Ranges | Ranges TS v1 已发布且合并入C++20 | Concepts | C++20 | C++20 |
Modules | 合并的设计已被C++20批准通过 | C++20 | C++20 | |
Coroutines | Coroutines TS v1 已发布且合并入C++20 | C++20 | C++20 | |
Executors | 新的折衷设计已被C++23批准通过 | C++26 | C++23 (已计划) | |
Contracts | 移到研究组 | C++26 | C++23 | |
Networking | Networking TS v1 已发布 | Executors | C++26 | C++23 (已计划) |
Reflection | Reflection TS v1 已发布 | C++26 | C++23 | |
模式匹配 | C++26 | C++23 | ||
模块化标准库 | C++23 | C++23 (已计划) |