void+c++
【CSDN 编者按】说起 C++ 语言,程序员们应该再熟悉不过了。它包含了 C 语言提供的所有功能。在应用程序中,C++ 无处不在。近日,Garmin 的一名软件工程师 Lucian Radu Teodorescu 在一篇文章中总结了目前 C++ 继任语言的技术状况。
原文链接:https://accu.org/journals/overload/30/172/teodorescu
作者 | Lucian Radu Teodorescu译者 | 禾木木出品 | CSDN(ID:CSDNnews)2022 年出现了许多可以与 C++ 竞争的语言。就在今年的 CPP North C++ 大会上,谷歌宣布了一门新的编程语言 Carbon,并称其将是「C++ 的继任者」。
对于这一事件,国外媒体和开发者们也询问了 C++ 之父 Bjarne Stroustrup 的看法,他表示:“这些年总是有新的语言试图成为 C++ 的继承者,我欢迎对编程语言和编程风格进行实验。但 Carbon 太新且规范不足,我无法真正做出有意义的技术评论。而通常在不开发全新语言规则、库和管理方案的情况下,很难提供 C++ 的替代方案。”
该语言发出后,也让一众网友浅来围观,有支持,也有反对的声音。
近日,Garmin 的一名软件工程师 Lucian Radu Teodorescu 在文章中报道了目前 C++ 继任语言的技术状况。
C++ 是一种特殊的编程语言,也是最常用的编程语言之一,但它也是最受批评的语言之一。根据 TIOBE 指数,30 年来,C++ 一直是排名前 4 的编程语言(使用12个月的平均值),并且还成功摘得了
参见下图,可了解过去 20 年的语言趋势(2022年10月的TIOBE编程社区指数)。
对于一种已经存在了近 40 年的编程语言来说,能经常出现在顶级编程语言的名单中,的确是一个伟大的成就。在颇受欢迎的同时,C++ 的批评声却接连不断,例如 Liunx 之父直接说 C++ 是一门糟糕的语言。大部分的人都在抱怨这种语言太大了,太复杂了,有一些是应该被扼杀的功能,有太多的功能,反之,又有些功能不够用。以偏概全,C++ 可以被看作是一个没有清晰连贯的故事的各种功能的随机集合。
在为该语言辩护时,Bjarne Stroustrup 认为,"在 C++ 中,有一种更小、更干净的语言正在努力摆脱"。这句话在 28 年后的今天仍然被广泛使用。虽然这句话意在为 C++ 辩护,但如果仔细分析一下,就会发现这也是一种隐含的批评。C++ 仍然没有成为人们所期望的那种更小、更干净的语言。它可能仅仅意味着这种更小更干净的语言只是一个海市蜃楼。
意欲取代 C++ 的编程语言
那么问题来了,怎样才能获得一个更好的编程语言呢?它比现在的 C++ 更简单、更干净,并且与 C++ 占据同样的空间(系统编程语言)?一个 C++ 的继任语言是什么样子的?
虽然过去也有一些尝试,但像 2022 年这样的还是很少见的,一下子有 3 种继任者语言在 C++ 主题演讲中公布。
首先,有 Dave Abrahams 和 Dimitri Racordon 在 C++ Now 上宣布的 Val。Val 的核心思想是,我们可以使用可变值语义建立安全且高效的程序。
两个月后,在 CppNorth 上,Chandler Carruth 宣布了 Carbon 语言。Carbon 语言试图解决 C++ 的几个方面:几十年来积累的技术债务、优先考虑向后兼容性和 C++ 的进化过程。
又过了两个月,在 CppCon 上,Herb Sutter 宣布了 CppFront,作为 C++ 的可能继承者。他的主要目标是 "使 C++ 本身向前发展,并使 C++ 加倍发展",防止用户迁移到其他语言。宣称的目标是使 C++ 的安全性提高 50 倍,简单 10 倍。
本文作者 Lucian Radu Teodorescu 试图对这三种语言提供一个批判性的观点。他解释道:“这样做并不是认为它们不能成为 C++ 的继承者;恰恰相反,我试图在希望取代 C++ 的位置之前列出这些语言在需要解决的问题。虽然我确实有一些个人偏见,但我会尽力客观地进行分析。”
早期取代者
D 编程语言由 Walter Bright 创建,出现在 2001 年;在 2007 年时,Andrei Alexandrescu 加入了设计和开发工作。这种语言本应从 C++ 的错误中学习,并成为其继承者。它承诺了同样的效率水平,但增加了大量的新功能,并简化了 C++ 的一些更复杂的部分。D 的主页将 D 宣传为一种可以 "写得快、读得快、跑得快 "的语言。
D 已经吸引了一些商业用户,但可以说它并没有达到重要的编程语言的地位。Andrei 是作者长期以来的偶像之一,而且对 Walter 相当尊敬,但主要把 D 看作是一个语言功能的大集合,松散地绑在一起。在我看来,这门语言缺乏一个清晰的基础,可以让所有的功能都有凝聚力。
Go 编程语言于 2009 年由谷歌推出;1.0 版本于 2012 年发布。这种语言的目标是让程序员 "大规模地构建快速、可靠和高效的软件"。Go 语言的设计者不喜欢 C++,因此,Go 似乎更像是 C 的进化,而不是 C++ 的进化。Go 在 2022 年才增加了泛型,并且仍然缺乏广泛使用的功能,如异常处理。
虽然 Go 可以说是一种成功的编程语言,但它的成功主要是在云计算业务中。尽管它取得了相对的成功,但它不能被称为 C++ 的继承者。
Rust 是 Mozilla 开发的一种编程语言,2010 年时公布,第一个版本在 2015 年发布。Rust 专注于可靠(内存和线程安全)和高效的软件。Rust 语言模型是围绕着所谓的借用检查器,它能跟踪所有对象的生命周期;因此,它可以在编译时检测安全错误,并不需要使用垃圾收集器。
Rust 虽然不像 Go 那样流行,但似乎被认为是 C++ 的良好替代品。问题是,Rust 和 C++ 之间没有清晰/干净/通用的接口方式,这使得想转到 Rust 的 C++ 程序员经历了突然的迁移。
Val
Val 给自己的目标定位是:
快速的定义
默认情况下是安全的
简单
可与 C++ 互操作
Val 以这些目标针对 C++、Rust 和 Swift 语言的受众。它的目标是实现 C++ 的性能,但要比 Rust 更简单的方式保证安全。在性能方面,Val 旨在减少编写安全软件所需的对象复制和内存分配的数量。在安全性方面,Val 中的所有结构都保证是安全的,除非用户明确要求额外的控制(将代码的一部分标记为不安全)。该语言的简单性主要来自于它对 Swift 的强烈影响,通常被认为是一种简单易用的语言。
许多编程语言不一定有一个贯穿其所有功能的核心思想,就像语言的催化剂一样;这会给人的印象是这些语言缺乏连贯性。这不能说是 Val 的问题。这门语言突出之处在于它有一个模型可以在程序上消除安全问题:它被称为 Mutable Value Semantics(变值语义)。但是,在这之前,一起先来探讨一下它所解决的主要问题。
C++ 本质上是不安全的
这一切都始于这样的观察:在存在突变的情况下,引用语义可能会导致不安全的程序。因为引用语义允许创建复杂的依赖关系图,所以突变不能保证在整个图中保留安全性。例如,如果一个函数对两个对象进行操作并改变了其中一个对象时,就不能保证另一个对象不会以完全意想不到的方式发生变化。这在单线程和多线程环境中都会产生问题。此外,如果不深入检查所有可能受到影响的代码,程序员们也没有系统的方法来验证突变的后果。这简直打破了结构化编程的核心思想。
以下面这个 C++ 代码片段为例:
void append_vec(vector& dest, const vector& src) { for ( auto x: src ) dest.push_back(x); }忽略执行中的低效率,这段代码有一个严重的安全问题。而且,如果只看这段代码,就不容易发现这个问题;还必须看一下周围的代码。如果此函数的调用者提供相同的向量作为源参数和目标参数,那么就会导致未定义的行为。
为了确保像这样的函数有正确的语义,则需要一个独立性的保证:程序员们需要确保所交互的对象(至少写给其中一个对象)是不相同的。这在语言中无法得到适当的执行;因此,就处于不安全的领域。
这里的问题比它看起来要复杂得多。如果一个函数的两个参数都是引用(也就是说,我们没有在其中改变任何东西),那么就没有问题。只有当我们有 mutation.const 时,问题才会出现。
Swift 通过使用 copy-on-write 技术来解决这个问题,但这可能会导致效率低下。
Rust 通过跟踪对象的生命周期来解决这个问题。这给程序员增加了负担,而且会给程序增加不必要的限制。
可变值语义
函数式编程语言通过禁止突变来避免上述问题。可以对多个对象有多个引用,因为没有人可以改变这些对象。这对许多程序员来说感觉很不自然,而且对无数的算法来说效率很低。
Val 以一种完全不同的方式解决了这个问题:它对引用增加了限制,并确保没有人可以读取一个对象,而其他人却可以改变它。
Val 认识到整体/部分关系的重要性。这些关系只能形成一棵树,而不是一个循环图。如果想修改这棵树上的一个对象,马上就能知道这个变化的影响,也就是所有其他可能受到这个突变影响的对象。它允许程序员们推理出哪些对象可以安全地作为读和写传入一个函数。
最后,按照这个逻辑,可以安全地添加引用来表示整体/部分关系。
在 Val 模型中,突变是不被禁止的,但是每次突变一个对象时,编译器可以计算出哪些对象可以安全地读取,哪些对象可以同时安全地写入。安全性可以通过构造来保证。
消除对象之间的任意引用并关注整体/部分关系是赋予 Val 价值语义的原因。但是,由于 Val 也允许值的突变,就可以把这个模型称为可变值语义学。
科学的方法
走到这一步,作者认为很重要的一个方面:Val 似乎遵循了一种科学的方法。可以看到,在上述内容简单地描述了一个确保安全的计算模型。这不仅仅是作者提出的关于语言安全的主张。他们有一个安全的证明,在语言的限制下。
该语言的主要创造者 Dimitri Racordon,实际上是一名博士后研究员。Dave Abrahams 似乎也是志同道合的人。Dave 和 Sean Parent 一起重新组建了 Adobe 的 STLabs。可以看出 Alex Stepanov(STL的创造者,也是STLabs的前成员)对 Dave 和 Sean 的研究导向的影响。
不能保证 Val 会像 C++ 那样成功,但可以发现解决 C++ 的一些基本问题的合理方法:清楚地定义问题,然后提出一个通用而优雅的解决方案。
使用临时引用
Val 简单地指出使用临时引用是不安全的。这使得人们不清楚如何实现需要引用的程序,而不是表达整体/部分关系。
例如,实现一个双链表需要不能被模拟为整体/部分关系的引用。目前还不清楚如何实现具有可变值语义的双链表。另一个例子,考虑一个应用程序中的共享缓存组件。根据定义,这样的组件需要被多方访问,并且需要允许突变。同样,我们也不清楚如何在 Val 中实现这一点。
也许这些例子的简单答案是,用户必须将一些代码标记为不安全。这也许是可以的;作为语言的使用者,我们只是缺乏如何处理这些情况的经验。Val 必须为处理这些情况提供良好的指导。
C++ 的互操作性
在写这篇文章的时候,Val 还没有明确的公开计划如何来处理与 C++ 的互操作性,它只是宣布了它的意图。为了成为 C++ 的继任语言,Val 需要解决这个问题。而且,这个问题似乎并不容易。
首先要注意的是,根据它的描述,Val 的灵感主要来自 Swift。这意味着 Val 和 C++ 之间的差距不小(一边是 Carbon 和 Cpp2 的差距,另一边是 C++ 的差距)。缩小这个差距可能需要很大的努力。
第二个障碍是可变值语义系统所带来的限制。C++ 本质上包含了大量的临时引用。这意味着,C++ 代码在 Val 中会被视为包含无数的不安全操作。在作者看来,几乎所有的 C++ 操作都应该在 Val 中被标记为不安全。这似乎增加了互操作性的差距。
请注意,作者并不是说 Val 不能与 C++ 适当地互操作。只是想表述实现这一点可能不是一个简单的努力。
Carbon
Carbon 是在 CppNorth 2022 上面世,意欲成为 C++ 继任语言。Carbon 得到了谷歌的支持(据 Chandler 说,也得到了 Adobe 的支持)。此外,一个有趣的事实是,谷歌则在 CppCon 2022 上缺席;也许这是谷歌在考虑放弃 C++ 的一个标志。
在演讲中,Chandler 列举了目前 C++ 的问题。
大量的技术债务
C++ 优先考虑向后兼容,而不是语言演进;这也阻碍了对技术债务的修复
国际标准化组织的语言发展过程并没有针对 C++ 发展的实际需求进行优化。
Chandler 认为,解决这些问题的办法是开始考虑 C++ 的后继任语言。类似于 C++ 被创造为 C 的继承者,Swift 被创造为 ObjectiveC 的继承者,Kotlin 被创造为 Java 的继承者,则需要找到 C++ 的继承语言。
为了创建一个 C++ 的继任语言,需要在现有的生态系统中构建,提供双向的互操作性,并确保有工具来帮助迁移和学习。而这些实际上就是新宣布的 Carbon 语言的目标。
与 C++ 相比,Carbon 似乎没有一个标志性的特征。它就像是一个 C++ 的清理项目。在演讲中,Chandler 展示了更简洁的语法、更干净的指针语义、更好的包装、更好的公共/私有成员的默认值、显式参数、继承清理、API 扩展点和 C++ 0x 风格的泛型。所有这些功能都以这样或那样的方式存在于其他编程语言中。
Carbon 可以被看作是具有更好的默认值的 C++,这是件好事。人们会看到一种熟悉的语言更好/更简单。Carbon 的学习曲线可以很平滑,从 C++ 到 Carbon 的过渡不需要跳过太多的障碍。
但是,另一方面,这与 D 有什么不同?D 也试图通过学习 C++ 的错误和清理其粗糙的边缘而成为 C++ 的继承者。是什么让 Carbon 语言具有内部一致性,而不是让它感觉像一群不相关的功能?
如果从进化的角度来看,即使今天所有的默认值都很有意义,又有什么能保证它们在接下来的几十年里都有意义?怎样才能防止 Carbon 积累技术债务?这个问题的部分答案是,正如 Chandler 提到的,使用工具来协助迁移。但是,都看到了从 Python 2 迁移到 Python 3 是多么的痛苦;可能不是每个人都相信工具可以帮助解决未来的问题。
这些问题都是 Carbon 团队需要回答的问题。作者表示并不是想说这些问题很难回答,但它们需要被回答。
与 C++ 的互操作性是困难的
即使 Carbon 可以成为一个具有更好的默认值的 C++,与 C++ 的互操作性也不一定容易。下面是 Sean Baxter 提出的一些观点:
在 Carbon 中没有功能过载
在 Carbon 中没有异常处理
在 Carbon 中没有多重继承,但人们仍然可以在 C++ 中使用它
与 C++ 不同,Carbon 不处理原始指针
Carbon 没有构造函数
从这些方面来看,可以很容易地看出,与 C++ 的互操作性将是一个复杂的问题。最有可能的是,即使互操作性问题能够完全解决,对于大型软件来说,从 C++ 迁移到 Carbon 也不会是一个简单的过渡。
文化的兴衰
谷歌是一家坚信文化是软件开发的驱动力的公司。Chandler 在他的主题演讲中也用 Peter Drucker 的一句话表达了这一点。
文化把战略当作早餐,把技术当作午餐,把产品当作晚餐,不久也会把其他一切都吃掉。
虽然企业文化确实是必不可少的,但仅仅引用 Peter Drucker 的话并不是成功的秘诀。主要问题是很难衡量文化及其影响。Chandler 列出了关于 Carbon 文化的几个要点(包容性、社区友好等)。虽然所有这些观点都是好的,但它们不足以定义文化,也不足以让文化在 Carbon 项目中发挥作用。例如,Chandler 没有提到卓越的技术、毅力、尝试新事物的勇气,或者如何优先考虑不同的(与文化有关的)目标。
Lucian Radu Teodorescu 表示在他以前工作的一家公司,有一句口头禅是 "我们从不让项目失败"。谷歌和 Carbon 项目的文化中是否有一个类似的目标?人们似乎把谷歌看作是一家尝试许多产品并在一段时间后关闭它们的公司。例如,如下图,Victor Zverovich 的一条推特,他利用这种看法开了一个关于 Carbon 的玩笑。考虑到 Chandler 还宣布谷歌有一个不同的团队有同样的目标,但他们从 Rus t开始,转向 C++ 后,这种思路可能并不太牵强。
Lucian Radu Teodorescu 表示文化是好的,Chandler 提出的观点也是好的。但是,想要说服一名工程师则需要可验证的论据。
治理模式
关于 Carbon 公告的一个有趣之处是治理模式。Carbon 项目的目标是实现一种没有任何公司能决定语言未来的治理。每个人都可以通过创建拉动请求来参与语言的发展,但越是重要的功能,就越需要分析/论证。
对于没有达成共识的重要功能,有一个由三名成员(Chandler Carruth, Kate Gregory, Richard Smith)组成的指导委员会,负责达成决定。他们没有机会对设计做出贡献;他们只需要权衡提交给他们的论据并做出选择。
有趣的是,这个模型试图强调一个民主的过程,这在某种程度上类似于 ISO 的目标。这只是对参与各方的不同划分,当陷入僵局时会有更明确的规则来做什么。如果从事 C++ 标准化工作的人也从事 Carbon 的工作,那么 Carbon 的过程是否会明显好转就不清楚了。
虽然民主方法是目前最好的治理方式,但我们最近看到了一系列重大的政治失败,这些失败可能与民主的负面影响直接相关。值得一提的是,在古希腊,民主被认为是一种糟糕的治理方式。
Cpp2
CppFront 是 Herb Sutter 在 CppCon 2022 的闭幕主题演讲中宣布的一个项目。它是一个转码器,可以将 "更好的 C++",即 Cpp2,转换为旧的 C++。虽然 CppFront / Cpp2 是今年正式宣布的,但 Herb 已经在这个项目上工作了大约 7 年;每年,Herb 都会展示 Cpp2 的一小部分。
Herb 希望改进 C++(即10倍),而不是进行增量式的改变(即10%)。他希望使 C++ 实现 30 年前 Stroustrup 设想的那个更简单、更干净的语言的老目标。有趣的是,它采用了 Stroustrup 想改进 C 语言时相同的方法:开始一种新的语言并将代码翻译成以前的语言。因此,CppFront 是一个小型转译器,它接收 Cpp2 代码(Herb的新语言)并输出常规的 C++ 代码。
Herb 还设定了一些指标,我们可以用这些指标来评估这个实验是否成功。更安全50倍(也就是减少98%的CVE),更简单10倍(减少90%的教学指导)。预先定义指标是一个很好的策略,能够评估实验的成功;我非常喜欢这个想法。
向后兼容性和互操作性
通过放弃向后兼容性,Cpp2 可以比 C++ 更简单。这最终允许该语言删除那些被认为是有害的功能,并重新审视一些被证明是次优的设计选择。通过放弃向后兼容性,Cpp2 最终可以解决 C++ 中几十年积累的技术债务。
说实话,在 C++ 中优先考虑向后兼容性优先于语言发展并不是一个可靠的例子。每次我们为语言添加一个主要的功能(例如,概念、程序、模块等)时,我们实际上是在语言中创造一个新的时代。新的代码可以与旧的代码互动,但旧代码不能简单地依赖用新特性编写的新代码。尽管 C++ 标准没有正式提及语言时代,但是在语言中有一个底层的时代系统,由新特性的发布所决定。
可以将 Cpp2 看作是 C++ 的一个主要新特性。在互操作性和工具方面,事情要复杂一些,但本质是一样的。在同一个应用程序中,旧式 C++ 不能与 Cpp2 共存,这在技术上没有充分的理由。
按照设计,Cpp2 在语义上与 C++ 接近;这使得互操作性更容易。另一方面,这也会阻止 Cpp2 拥有与 C++ 完全不同的特性。例如,Cpp2 就很难使用 C++ 0x 式的泛型。
解决安全问题
安全性提高 50 倍的目标听起来令人印象深刻。如果 Cpp2 能够实现这个目标,我相信大多数语言的用户都会感到高兴。
让我们从这个数字的角度来全面了解其影响。这意味着 98% 的 C++ 应用程序如果被翻译成 Cpp2 就不会再崩溃了(假设崩溃只由不安全的应用程序产生)。或者说,98% 的 C++ 网络应用不会有漏洞(如果没有其他非C++的漏洞)。这将大幅减少崩溃和安全漏洞。
这似乎好得令人难以置信。实际上,如果我们更详细地分析,这些数字似乎太高了。
首先,如果讨论安全问题,需要清楚地知道什么是安全。安全性包括:
类型安全
边界安全
生命周期安全
初始化安全
对象访问安全
线程安全
算术安全
Herb 在他的主题演讲中提到了上述的前4个项目。然而,这些安全项目的所有方面并没有得到解决。作为一个主要的例子,在存在原始 pointer 时不能保证生命周期安全;仅仅检查 pointer 是远远不够的。也没有任何一个功能来检测 pointer .null 的使用后删除情况。
Cpp2,正如 CppCon 主题演讲中所描述的,无法检测到这段代码的问题:
vec.push_back(vec.front());Herb 定义了他的安全指标,包括前四个安全组件;故意忽略其他类型的安全似乎很奇怪。尤其是如果被忽略的安全成分很重要的话。
对象访问安全是指受对象访问模式影响的安全规则。一般来说,这一类的不安全代码可以转化为类型安全、边界安全或生命周期安全。无效迭代器的规则是这个类别中很好的例子。
线程安全是 C++ 的一个大问题,Herb 完全没有提到。在她 2021 年的 C++ Now 演讲中,Anastasia Kazakova 展示了数据,显示在 C++ 社区中,并发安全占用户 setback 的 27%。相比之下,边界安全问题只占 16%,使用后删除问题占用户 setback 的 15%。并发安全是安全性方面最大的痛点,而这一点没有在 Herb 的列表中得到体现。
Herb 在他的幻灯片上表示,Cpp2 获得了 "结构安全"。这不可能是真的。结构安全性应该是指语言的构建方式总是能够导致安全的构造(除非程序员真的忽略了类型系统并将安全性掌握在自己手中)——类似于 Val 或 Rust 的构建方式。但 Cpp2 并没有这样做;它只是对一些常见的不安全行为的来源增加了更多的安全检查。如果你看过 Dave Abrahams 和 Dimitri Racordon 的演讲,以及 Sean Parent 的演讲,这一点应该马上就能看出来。
这让我相信,在安全性上提高 50 倍是不可能实现的目标。
关于目标的可衡量性
理论上,在任何时候,我们都可以根据这些指标来衡量进展,可以评估这个实验是否成功或能否成功。
让我们从第二个指标开始:简单 10 倍,就像我们需要在 C++ 书籍中教授的指导中衡量的那样。在这个实验被证明是成功之前,人们不太可能写关于 Cpp2 的书,但可以想象这样一本书的内容是什么。可以确定哪些是我们需要教授的关于 Cpp2 的一系列概念,并且我们可以将其与我们目前正在教授的关于 C++ 的内容清单进行比较。因此,我们可以衡量这个指标。
这并不像人们想象的那样简单。C++ 有很长的历史;因此我们知道它的陷阱,人们在 C++ 书籍中记录了这些陷阱。但是,Cpp2 没有这么丰富的历史,所以,人们总是怀疑我们不知道它的所有陷阱。然而,Cpp2 与 C++ 如此接近,我真诚地相信可以排除这些顾虑,得到一个关于简单性的准确测量。
但是,我不能对第二个指标说同样的话。我们如何衡量 CVE 和安全漏洞的百分比?首先需要有一个足够大的 Cpp2 程序的语料库,由大量的程序员和公司编写。然而,为了实现这一点,Cpp2 需要被认为是一种成功——一种循环的依赖。因此,在 Herb 的演讲中定义的安全度量并不是衡量实验成功的指标。
在主流语言使用一段时间后,使用这个指标来评估语言是有意义的,但不能判断实验的成功。
有还是没有 monads
在主题演讲的1小时33分(以YouTube视频为参考)中,Herb Sutter 骄傲地说:"我没有说过一次 monads 这个词"。然后他继续解释说,Cpp2 是关于我们目前在 C++ 中使用的语言理念;而不是来自其他语言的奇怪的外来术语。
虽然这句话可能会吸引 C++ 社区中以自我为中心的部分人,但我认为它对社区的伤害要大于帮助。
首先,C++ 到处都在使用 monads。新的 C+ +23 特性可能是使用 monads 的一个已知例子,但 C++ 从根本上说是围绕着 monads 建立的。当我们调用可能抛出异常的函数时,我们隐含地使用了 monads 。也就是说,几乎到处都是。
其次,它在语言用户中创造了一种自给自足的感觉。这样的声明不是向社区开放新的想法,而是传递了一个信息:C++ 不需要向其他语言学习。但是,该语言拥有的大量技术债务,以及三种继任语言的出现,证明了这一点。
比较
下面的表中试图提供三种语言之间的比较;C++ 也是一个基准。
今年宣布的 3 种 C++ 继任语言都被认为是试验品。并没有很好的指标表明它们是否真的能成功地吸引足够数量的编码人员/代码库,在生产环境中使用它们。
看看 GitHub 上的星星数量,我们看到 Carbon 是这群人中的佼佼者,与其他两个相比,有很大的差距。Carbon 已经成功地在社区内进行了更多的炒作;对包容性的关注和治理模式可能对此有贡献。
这三种语言也在它们与 C++ 的相似程度方面有所区别。正如所料,Cpp2 是三种语言中最接近 C++ 的。Carbon 似乎离 C++ 更远,但使用了与 C++ 相同的基本构件块;在 Carbon 中,用户的思考方式与他们在 C++ 中的方式基本相同。由于可变值语义,Val 程序员在编程时需要有一个稍微不同的思维模型,这可能使 Val 成为一种离 C++ 更远的语言。另一方面,如果我们看一下 Val 的快速定义口号,特别是在默认安全和简单的背景下,该语言的原则似乎可以很好地转化为 C++ 的受众。
在这三种新的语言中,Val 是唯一一种能够支持其安全承诺的语言。其他两种语言试图改变一些最不安全的操作的默认值;目前还不清楚这是否有很大的区别。
就语言特性的一致性而言,这三种语言似乎都比 C++ 更好。但在语言的连贯性方面,改变默认值并不能让你走得那么远。在这里,与 Carbon 和 Cpp2 相比,Val 的方法似乎更有连贯性。
最后,我认为在我们这样的工程学科中很重要的一点是:有多少语言设计决定是由某种科学支持的?在这方面,Val 似乎是唯一有一些理论基础的。这可以为其用户提供真正的保证。
放弃还为时过早
Herb 在他的主题演讲中呼吁不要放弃 C++。这是一个来自 C++ 的领导层的证明,人们正在考虑放弃 C++。在一年内出现了三种 C++ 的继任语言,正好证实了这一想法。C++ 是否开始默默无闻还不得而知,但我们大概可以认为,今年是 C++ 未来的一个拐点。
目前,要判断这些实验是否会成功还为时过早。所有的语言都有优点,也都有弱点。如果其中至少有一种成功了,我相信我们会推进编程语言的实践;这可能意味着在整个软件行业的积极影响。
在这次比较中,尽可能地保持了客观,但我确实有自己的偏见。我希望这些偏见不会妨碍在比较这些语言时做得很好。
说到偏见,我确实需要承认:在业余时间,我已经开始与 Val 团队合作,推动语言的核心理念。对我来说,这些想法,如果能在实践中得到完善和成功采用,比特定的语言更重要。如果 Val 作为一种编程语言消亡了,但它的所有想法都被纳入了 C++,那么我会很高兴。
自从我看到 Dave 和 Dimitri 在 C++ Now 上的演讲录音后,我就被可变值语义的思想所吸引。在 2022 年的 CppCon 上,我见到了 Dave 和 Dimitri,并和他们一起探讨了一些细节,使我相信 Val 背后的想法是深刻的,经过深思熟虑的,值得密切关注。
看一下流行的数字,Val 的表现并不那么好。可能其中一个原因是,好的想法需要时间来沉淀。套用一个著名的演讲,我选择为 Val 工作,不是因为它容易,而是因为它困难;因为 Val 的目标是值得的。
引用:
[ADSP22] Connor Hoekstra, Bryce Adelstein Lelbach, Connor, Sean Baxter, ADSP: The Podcast, Episode 97: ‘C++ vs Carbon vs Circle vs CppFront with Sean Baxter’, 2022, https://adspthepodcast.com/2022/09/30/Episode-97.html
[Abrahams22a] Dave Abrahams, A Future of Value Semantics and Generic Programming (part 1), C++ Now 2022,
https://www.youtube.com/watch?v=4Ri8bly-dJs
[Abrahams22b] Dave Abrahams, Dimitri Racordon, A Future of Value Semantics and Generic Programming (part 2), C++ Now 2022, https://www.youtube.com/watch?v=GsxYnEAZoNI&list=WL
[Abrahams22c] Dave Abrahams, ‘Values: Safety, Regularity, Independence, and the Future of Programming’, CppCon 2022
[Carbon] GitHub, Carbon Language: An experimental successor to C++, https://github.com/carbon-language/carbon-lang
[Carruth22] Chandler Carruth, ‘Carbon Language: An experimental successor to C++’, CppNorth 2022, https://www.youtube.com/watch?v=omrY53kbVoA
[Kazakova21] Anastasia Kazakova, ‘Code Analysis++’, CppNow, 2021, https://www.youtube.com/watch?v=qUmG61aQyQE
[Parent22] Sean Parent, ‘Exceptions the Other Way Around’, https://www.youtube.com/watch?v=mkkaAWNE-Ig
[Racordon22a] Dimitri Racordon, Denys Shabalin, Daniel Zheng, Dave Abrahams, Brennan Saeta, ‘Implementation Strategies for Mutable Value Semantics’
https://www.jot.fm/issues/issue_2022_02/article2.pdf
[Racordon22b] Dimitri Racordon, ‘Val Wants To Be Your Friend: The design of a safe, fast, and simple programming language’, CppCon 2022, https://www.youtube.com/watch?v=ELeZAKCN4tY&list=WL
[Stroustrup94] Bjarne Stroustrup, The Design and Evolution of C++, Addison-Wesley Professional, 1994
[Sutter22] Herb Sutter, ‘Can C++ be 10× simpler & safer … ?’, CppCon 2022, https://www.youtube.com/watch?v=ELeZAKCN4tY&list=WL
[TIOBE22] TIOBE, TIOBE Index for October 2022, October 2022, https://www.tiobe.com/tiobe-index/ (last accessed October 2022)
[Wikipedia] Wikipedia, C++, https://en.wikipedia.org/wiki/C%2B%2B#Criticism
[Val] The Val Programming Language, https://www.val-lang.dev/
[Zverovich22] Victor Zverovich, ‘Google will soon have…’, Twitter, 2022, https://twitter.com/vzverovich/
Lucian Radu Teodorescu has a PhD in programming languages and is a Staff Engineer at Garmin. He likes challenges; and understanding the essence of things (if there is one) constitutes the biggest challenge of all.
《2022-2023 中国开发者大调查》重磅启动,欢迎扫描下方二维码,参与问卷调研,更有 iPad 等精美大礼等你拿!
屠陆狱2668c++ void **变量名的用法 -
邱丁面14773755576 ______ 双重指针,就是一址指向的也是一个指针.给个例子:int number;//这是一个普通的变量 int *p2n=&number;//这是一个指针,他存储的地址是变量number的地址,通过这个地址,可以定位到number这个变量 int **p2p=&p2n;//这是一个指针的指针,他存储的地址是指针变量p2n的地址,通过他,可以确定p2n这个指针bianliang.void 是指,这个变量pp1存储的地址,不确定一个具体的类型,你可以在必要的时候使用(类型 **)的方式进行类型转换.
屠陆狱2668c++中的void是干什么的? -
邱丁面14773755576 ______ 这个方法是一个空返回值或无返回值的方法
屠陆狱2668void*&,void**在C++中代表的什么意思? -
邱丁面14773755576 ______ viod *&a 先取a的地址再作指针运算,由于&和*是相同级别运算符,按从右向左的方向,相当于 void*(&a); void**a是指向指针的指针,
屠陆狱2668请问在c++中,void作为标识符是如何使用的? -
邱丁面14773755576 ______ void f(void) { } f前面的void是表示函数返回空值;()内的事表示函数参数为空;
屠陆狱2668c语言里void 语句(void)是什么意思?知道的大虾说下??谢谢 -
邱丁面14773755576 ______ 在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理.因此,为了避免混乱,在编写C/C++程序时,对于任何函数都必须一个不漏地指定其类型.如果函数没有返回值,一定要声明为void类型.这既是程序良好可读性的需要,也是编程规范性的要求.另外,加上void类型声明后,也可以发挥代码的“自注释”作用.代码的“自注释”即代码能自己注释自己.
屠陆狱2668在c语言中,void main()中的void的作用是什么,换成int又是什么意思 -
邱丁面14773755576 ______ void表示主函数为空函数,没有返回值;而改为int后则表示主函数必须返回一个int值,需在main最后加个【return 一整型值;】返回一个整型值
屠陆狱2668c++ 自定义函数 void -
邱丁面14773755576 ______ 函数前的修饰符void表示该函数无返回值,但函数内部输出仍正常. 如: void sum1(int x, int y) { cout << x+y << endl; } int sum2(int x, int y) { return x+y; } void main() { int x=3, y=4, z; sum1(x, y);//直接输出7 z = sum2(x, y);//将返回的值赋给z cout << z << endl; //z = sum1(x, y);不可以这样写,因为sum1申明为void,表示无返回. }
屠陆狱2668C++中void main()那个void是什么作用啊? -
邱丁面14773755576 ______ VOID在C和C++都是一种数据类型,表示无返回值类型. 在C中不能用在main()前面,只能用在其它函数,而在C++中则可用于main()前面
屠陆狱2668c++ 函数调用 自定义函数void -
邱丁面14773755576 ______ void 就是函数执行后不返回值,也就是最后没有 return.有关补充的问题,不知道你到底是什么意思.有的值想返回就用return 返回,有的值不想返回就不去管它就可以了.取决于你函数定义的功能是什么.如果你不想处理函数的返回值,就不用提取函数的返回值就可以了.
屠陆狱2668C++函数的参数为 void *类型表是什么意思?? -
邱丁面14773755576 ______ void参数表示没有参数的意思,和()表示的意思是一样的 void * 表示有一个指针类型的参数,无论是什么类型的指针,只要是指针就可以