作者 | Lucian Radu Teodorescu
譯者 | 禾木木
出品 | CSDN(ID:CSDNnews)
(資料圖)
2022 年出現(xiàn)了許多可以與 C++ 競爭的語言。就在今年的 CPP North C++ 大會(huì)上,谷歌宣布了一門新的編程語言 Carbon,并稱其將是「C++ 的繼任者」。
對于這一事件,國外媒體和開發(fā)者們也詢問了 C++ 之父 Bjarne Stroustrup 的看法,他表示:“這些年總是有新的語言試圖成為 C++ 的繼承者,我歡迎對編程語言和編程風(fēng)格進(jìn)行實(shí)驗(yàn)。但 Carbon 太新且規(guī)范不足,我無法真正做出有意義的技術(shù)評論。而通常在不開發(fā)全新語言規(guī)則、庫和管理方案的情況下,很難提供 C++ 的替代方案?!?/p>
該語言發(fā)出后,也讓一眾網(wǎng)友淺來圍觀,有支持,也有反對的聲音。
近日,Garmin 的一名軟件工程師 Lucian Radu Teodorescu 在文章中報(bào)道了目前 C++ 繼任語言的技術(shù)狀況。
C++ 是一種特殊的編程語言,也是最常用的編程語言之一,但它也是最受批評的語言之一。根據(jù) TIOBE 指數(shù),30 年來,C++ 一直是排名前 4 的編程語言(使用12個(gè)月的平均值),并且還成功摘得了
2022 年的年度編程語言稱號(hào)
。
參見下圖,可了解過去 20 年的語言趨勢(2022年10月的TIOBE編程社區(qū)指數(shù))。
對于一種已經(jīng)存在了近 40 年的編程語言來說,能經(jīng)常出現(xiàn)在頂級(jí)編程語言的名單中,的確是一個(gè)偉大的成就。在頗受歡迎的同時(shí),C++ 的批評聲卻接連不斷,例如 Liunx 之父直接說 C++ 是一門糟糕的語言。大部分的人都在抱怨這種語言太大了,太復(fù)雜了,有一些是應(yīng)該被扼殺的功能,有太多的功能,反之,又有些功能不夠用。以偏概全,C++ 可以被看作是一個(gè)沒有清晰連貫的故事的各種功能的隨機(jī)集合。
在為該語言辯護(hù)時(shí),Bjarne Stroustrup 認(rèn)為,"在 C++ 中,有一種更小、更干凈的語言正在努力擺脫"。這句話在 28 年后的今天仍然被廣泛使用。雖然這句話意在為 C++ 辯護(hù),但如果仔細(xì)分析一下,就會(huì)發(fā)現(xiàn)這也是一種隱含的批評。C++ 仍然沒有成為人們所期望的那種更小、更干凈的語言。它可能僅僅意味著這種更小更干凈的語言只是一個(gè)海市蜃樓。
意欲取代 C++ 的編程語言
那么問題來了,怎樣才能獲得一個(gè)更好的編程語言呢?它比現(xiàn)在的 C++ 更簡單、更干凈,并且與 C++ 占據(jù)同樣的空間(系統(tǒng)編程語言)?一個(gè) C++ 的繼任語言是什么樣子的?
雖然過去也有一些嘗試,但像 2022 年這樣的還是很少見的,一下子有 3 種繼任者語言在 C++ 主題演講中公布。
首先,有 Dave Abrahams 和 Dimitri Racordon 在 C++ Now 上宣布的 Val。Val 的核心思想是,我們可以使用可變值語義建立安全且高效的程序。
兩個(gè)月后,在 CppNorth 上,Chandler Carruth 宣布了 Carbon 語言。Carbon 語言試圖解決 C++ 的幾個(gè)方面:幾十年來積累的技術(shù)債務(wù)、優(yōu)先考慮向后兼容性和 C++ 的進(jìn)化過程。
又過了兩個(gè)月,在 CppCon 上,Herb Sutter 宣布了 CppFront,作為 C++ 的可能繼承者。他的主要目標(biāo)是 "使 C++ 本身向前發(fā)展,并使 C++ 加倍發(fā)展",防止用戶遷移到其他語言。宣稱的目標(biāo)是使 C++ 的安全性提高 50 倍,簡單 10 倍。
本文作者 Lucian Radu Teodorescu 試圖對這三種語言提供一個(gè)批判性的觀點(diǎn)。他解釋道:“這樣做并不是認(rèn)為它們不能成為 C++ 的繼承者;恰恰相反,我試圖在希望取代 C++ 的位置之前列出這些語言在需要解決的問題。雖然我確實(shí)有一些個(gè)人偏見,但我會(huì)盡力客觀地進(jìn)行分析?!?/p>
早期取代者
D 編程語言由 Walter Bright 創(chuàng)建,出現(xiàn)在 2001 年;在 2007 年時(shí),Andrei Alexandrescu 加入了設(shè)計(jì)和開發(fā)工作。這種語言本應(yīng)從 C++ 的錯(cuò)誤中學(xué)習(xí),并成為其繼承者。它承諾了同樣的效率水平,但增加了大量的新功能,并簡化了 C++ 的一些更復(fù)雜的部分。D 的主頁將 D 宣傳為一種可以 "寫得快、讀得快、跑得快 "的語言。
D 已經(jīng)吸引了一些商業(yè)用戶,但可以說它并沒有達(dá)到重要的編程語言的地位。Andrei 是作者長期以來的偶像之一,而且對 Walter 相當(dāng)尊敬,但主要把 D 看作是一個(gè)語言功能的大集合,松散地綁在一起。在我看來,這門語言缺乏一個(gè)清晰的基礎(chǔ),可以讓所有的功能都有凝聚力。
Go 編程語言于 2009 年由谷歌推出;1.0 版本于 2012 年發(fā)布。這種語言的目標(biāo)是讓程序員 "大規(guī)模地構(gòu)建快速、可靠和高效的軟件"。Go 語言的設(shè)計(jì)者不喜歡 C++,因此,Go 似乎更像是 C 的進(jìn)化,而不是 C++ 的進(jìn)化。Go 在 2022 年才增加了泛型,并且仍然缺乏廣泛使用的功能,如異常處理。
雖然 Go 可以說是一種成功的編程語言,但它的成功主要是在云計(jì)算業(yè)務(wù)中。盡管它取得了相對的成功,但它不能被稱為 C++ 的繼承者。
Rust 是 Mozilla 開發(fā)的一種編程語言,2010 年時(shí)公布,第一個(gè)版本在 2015 年發(fā)布。Rust 專注于可靠(內(nèi)存和線程安全)和高效的軟件。Rust 語言模型是圍繞著所謂的借用檢查器,它能跟蹤所有對象的生命周期;因此,它可以在編譯時(shí)檢測安全錯(cuò)誤,并不需要使用垃圾收集器。
Rust 雖然不像 Go 那樣流行,但似乎被認(rèn)為是 C++ 的良好替代品。問題是,Rust 和 C++ 之間沒有清晰/干凈/通用的接口方式,這使得想轉(zhuǎn)到 Rust 的 C++ 程序員經(jīng)歷了突然的遷移。
ValVal 給自己的目標(biāo)定位是:
快速的定義
默認(rèn)情況下是安全的
簡單
可與 C++?互操作?
Val 以這些目標(biāo)針對 C++、Rust 和 Swift 語言的受眾。它的目標(biāo)是實(shí)現(xiàn) C++ 的性能,但要比 Rust 更簡單的方式保證安全。在性能方面,Val 旨在減少編寫安全軟件所需的對象復(fù)制和內(nèi)存分配的數(shù)量。在安全性方面,Val 中的所有結(jié)構(gòu)都保證是安全的,除非用戶明確要求額外的控制(將代碼的一部分標(biāo)記為不安全)。該語言的簡單性主要來自于它對 Swift 的強(qiáng)烈影響,通常被認(rèn)為是一種簡單易用的語言。
許多編程語言不一定有一個(gè)貫穿其所有功能的核心思想,就像語言的催化劑一樣;這會(huì)給人的印象是這些語言缺乏連貫性。這不能說是 Val 的問題。這門語言突出之處在于它有一個(gè)模型可以在程序上消除安全問題:它被稱為 Mutable Value Semantics(變值語義)。但是,在這之前,一起先來探討一下它所解決的主要問題。
C++ 本質(zhì)上是不安全的
這一切都始于這樣的觀察:在存在突變的情況下,引用語義可能會(huì)導(dǎo)致不安全的程序。因?yàn)橐谜Z義允許創(chuàng)建復(fù)雜的依賴關(guān)系圖,所以突變不能保證在整個(gè)圖中保留安全性。例如,如果一個(gè)函數(shù)對兩個(gè)對象進(jìn)行操作并改變了其中一個(gè)對象時(shí),就不能保證另一個(gè)對象不會(huì)以完全意想不到的方式發(fā)生變化。這在單線程和多線程環(huán)境中都會(huì)產(chǎn)生問題。此外,如果不深入檢查所有可能受到影響的代碼,程序員們也沒有系統(tǒng)的方法來驗(yàn)證突變的后果。這簡直打破了結(jié)構(gòu)化編程的核心思想。
以下面這個(gè) C++ 代碼片段為例:
忽略執(zhí)行中的低效率,這段代碼有一個(gè)嚴(yán)重的安全問題。而且,如果只看這段代碼,就不容易發(fā)現(xiàn)這個(gè)問題;還必須看一下周圍的代碼。如果此函數(shù)的調(diào)用者提供相同的向量作為源參數(shù)和目標(biāo)參數(shù),那么就會(huì)導(dǎo)致未定義的行為。
為了確保像這樣的函數(shù)有正確的語義,則需要一個(gè)獨(dú)立性的保證:程序員們需要確保所交互的對象(至少寫給其中一個(gè)對象)是不相同的。這在語言中無法得到適當(dāng)?shù)膱?zhí)行;因此,就處于不安全的領(lǐng)域。
這里的問題比它看起來要復(fù)雜得多。如果一個(gè)函數(shù)的兩個(gè)參數(shù)都是引用(也就是說,我們沒有在其中改變?nèi)魏螙|西),那么就沒有問題。只有當(dāng)我們有 mutation.const 時(shí),問題才會(huì)出現(xiàn)。
Swift 通過使用 copy-on-write 技術(shù)來解決這個(gè)問題,但這可能會(huì)導(dǎo)致效率低下。
Rust 通過跟蹤對象的生命周期來解決這個(gè)問題。這給程序員增加了負(fù)擔(dān),而且會(huì)給程序增加不必要的限制。
可變值語義
函數(shù)式編程語言通過禁止突變來避免上述問題??梢詫Χ鄠€(gè)對象有多個(gè)引用,因?yàn)闆]有人可以改變這些對象。這對許多程序員來說感覺很不自然,而且對無數(shù)的算法來說效率很低。
Val 以一種完全不同的方式解決了這個(gè)問題:它對引用增加了限制,并確保沒有人可以讀取一個(gè)對象,而其他人卻可以改變它。
Val 認(rèn)識(shí)到整體/部分關(guān)系的重要性。這些關(guān)系只能形成一棵樹,而不是一個(gè)循環(huán)圖。如果想修改這棵樹上的一個(gè)對象,馬上就能知道這個(gè)變化的影響,也就是所有其他可能受到這個(gè)突變影響的對象。它允許程序員們推理出哪些對象可以安全地作為讀和寫傳入一個(gè)函數(shù)。
最后,按照這個(gè)邏輯,可以安全地添加引用來表示整體/部分關(guān)系。
在 Val 模型中,突變是不被禁止的,但是每次突變一個(gè)對象時(shí),編譯器可以計(jì)算出哪些對象可以安全地讀取,哪些對象可以同時(shí)安全地寫入。安全性可以通過構(gòu)造來保證。
消除對象之間的任意引用并關(guān)注整體/部分關(guān)系是賦予 Val 價(jià)值語義的原因。但是,由于 Val 也允許值的突變,就可以把這個(gè)模型稱為可變值語義學(xué)。
科學(xué)的方法
走到這一步,作者認(rèn)為很重要的一個(gè)方面:Val 似乎遵循了一種科學(xué)的方法??梢钥吹?,在上述內(nèi)容簡單地描述了一個(gè)確保安全的計(jì)算模型。這不僅僅是作者提出的關(guān)于語言安全的主張。他們有一個(gè)安全的證明,在語言的限制下。
該語言的主要?jiǎng)?chuàng)造者 Dimitri Racordon,實(shí)際上是一名博士后研究員。Dave Abrahams 似乎也是志同道合的人。Dave 和 Sean Parent 一起重新組建了 Adobe 的 STLabs??梢钥闯?Alex Stepanov(STL的創(chuàng)造者,也是STLabs的前成員)對 Dave 和 Sean 的研究導(dǎo)向的影響。
不能保證 Val 會(huì)像 C++ 那樣成功,但可以發(fā)現(xiàn)解決 C++ 的一些基本問題的合理方法:清楚地定義問題,然后提出一個(gè)通用而優(yōu)雅的解決方案。
使用臨時(shí)引用
Val 簡單地指出使用臨時(shí)引用是不安全的。這使得人們不清楚如何實(shí)現(xiàn)需要引用的程序,而不是表達(dá)整體/部分關(guān)系。
例如,實(shí)現(xiàn)一個(gè)雙鏈表需要不能被模擬為整體/部分關(guān)系的引用。目前還不清楚如何實(shí)現(xiàn)具有可變值語義的雙鏈表。另一個(gè)例子,考慮一個(gè)應(yīng)用程序中的共享緩存組件。根據(jù)定義,這樣的組件需要被多方訪問,并且需要允許突變。同樣,我們也不清楚如何在 Val 中實(shí)現(xiàn)這一點(diǎn)。
也許這些例子的簡單答案是,用戶必須將一些代碼標(biāo)記為不安全。這也許是可以的;作為語言的使用者,我們只是缺乏如何處理這些情況的經(jīng)驗(yàn)。Val 必須為處理這些情況提供良好的指導(dǎo)。
C++ 的互操作性
在寫這篇文章的時(shí)候,Val 還沒有明確的公開計(jì)劃如何來處理與 C++ 的互操作性,它只是宣布了它的意圖。為了成為 C++ 的繼任語言,Val 需要解決這個(gè)問題。而且,這個(gè)問題似乎并不容易。
首先要注意的是,根據(jù)它的描述,Val 的靈感主要來自 Swift。這意味著 Val 和 C++ 之間的差距不小(一邊是 Carbon 和 Cpp2 的差距,另一邊是 C++ 的差距)??s小這個(gè)差距可能需要很大的努力。
第二個(gè)障礙是可變值語義系統(tǒng)所帶來的限制。C++ 本質(zhì)上包含了大量的臨時(shí)引用。這意味著,C++ 代碼在 Val 中會(huì)被視為包含無數(shù)的不安全操作。在作者看來,幾乎所有的 C++ 操作都應(yīng)該在 Val 中被標(biāo)記為不安全。這似乎增加了互操作性的差距。
請注意,作者并不是說 Val 不能與 C++ 適當(dāng)?shù)鼗ゲ僮鳌V皇窍氡硎鰧?shí)現(xiàn)這一點(diǎn)可能不是一個(gè)簡單的努力。
Carbon
在演講中,Chandler 列舉了目前 C++ 的問題。
大量的技術(shù)債務(wù)
C++ 優(yōu)先考慮向后兼容,而不是語言演進(jìn);這也阻礙了對技術(shù)債務(wù)的修復(fù)
國際標(biāo)準(zhǔn)化組織的語言發(fā)展過程并沒有針對 C++ 發(fā)展的實(shí)際需求進(jìn)行優(yōu)化。
Chandler 認(rèn)為,解決這些問題的辦法是開始考慮 C++ 的后繼任語言。類似于 C++ 被創(chuàng)造為 C 的繼承者,Swift 被創(chuàng)造為 ObjectiveC 的繼承者,Kotlin 被創(chuàng)造為 Java 的繼承者,則需要找到 C++ 的繼承語言。
為了創(chuàng)建一個(gè) C++ 的繼任語言,需要在現(xiàn)有的生態(tài)系統(tǒng)中構(gòu)建,提供雙向的互操作性,并確保有工具來幫助遷移和學(xué)習(xí)。而這些實(shí)際上就是新宣布的 Carbon 語言的目標(biāo)。
與 C++ 相比,Carbon 似乎沒有一個(gè)標(biāo)志性的特征。它就像是一個(gè) C++ 的清理項(xiàng)目。在演講中,Chandler 展示了更簡潔的語法、更干凈的指針語義、更好的包裝、更好的公共/私有成員的默認(rèn)值、顯式參數(shù)、繼承清理、API 擴(kuò)展點(diǎn)和 C++ 0x 風(fēng)格的泛型。所有這些功能都以這樣或那樣的方式存在于其他編程語言中。
Carbon 可以被看作是具有更好的默認(rèn)值的 C++,這是件好事。人們會(huì)看到一種熟悉的語言更好/更簡單。Carbon 的學(xué)習(xí)曲線可以很平滑,從 C++ 到 Carbon 的過渡不需要跳過太多的障礙。
但是,另一方面,這與 D 有什么不同?D 也試圖通過學(xué)習(xí) C++ 的錯(cuò)誤和清理其粗糙的邊緣而成為 C++ 的繼承者。是什么讓 Carbon 語言具有內(nèi)部一致性,而不是讓它感覺像一群不相關(guān)的功能?
如果從進(jìn)化的角度來看,即使今天所有的默認(rèn)值都很有意義,又有什么能保證它們在接下來的幾十年里都有意義?怎樣才能防止 Carbon 積累技術(shù)債務(wù)?這個(gè)問題的部分答案是,正如 Chandler 提到的,使用工具來協(xié)助遷移。但是,都看到了從 Python 2 遷移到 Python 3 是多么的痛苦;可能不是每個(gè)人都相信工具可以幫助解決未來的問題。
這些問題都是 Carbon 團(tuán)隊(duì)需要回答的問題。作者表示并不是想說這些問題很難回答,但它們需要被回答。
與 C++ 的互操作性是困難的
即使 Carbon 可以成為一個(gè)具有更好的默認(rèn)值的 C++,與 C++ 的互操作性也不一定容易。下面是 Sean Baxter 提出的一些觀點(diǎn):
在 Carbon 中沒有功能過載
在 Carbon 中沒有異常處理
在 Carbon 中沒有多重繼承,但人們?nèi)匀豢梢栽?C++ 中使用它
與 C++ 不同,Carbon 不處理原始指針
Carbon 沒有構(gòu)造函數(shù)
從這些方面來看,可以很容易地看出,與 C++ 的互操作性將是一個(gè)復(fù)雜的問題。最有可能的是,即使互操作性問題能夠完全解決,對于大型軟件來說,從 C++ 遷移到 Carbon 也不會(huì)是一個(gè)簡單的過渡。
文化的興衰
谷歌是一家堅(jiān)信文化是軟件開發(fā)的驅(qū)動(dòng)力的公司。Chandler 在他的主題演講中也用 Peter Drucker 的一句話表達(dá)了這一點(diǎn)。
文化把戰(zhàn)略當(dāng)作早餐,把技術(shù)當(dāng)作午餐,把產(chǎn)品當(dāng)作晚餐,不久也會(huì)把其他一切都吃掉。
雖然企業(yè)文化確實(shí)是必不可少的,但僅僅引用 Peter Drucker 的話并不是成功的秘訣。主要問題是很難衡量文化及其影響。Chandler 列出了關(guān)于 Carbon 文化的幾個(gè)要點(diǎn)(包容性、社區(qū)友好等)。雖然所有這些觀點(diǎn)都是好的,但它們不足以定義文化,也不足以讓文化在 Carbon 項(xiàng)目中發(fā)揮作用。例如,Chandler 沒有提到卓越的技術(shù)、毅力、嘗試新事物的勇氣,或者如何優(yōu)先考慮不同的(與文化有關(guān)的)目標(biāo)。
Lucian Radu Teodorescu 表示在他以前工作的一家公司,有一句口頭禪是 "我們從不讓項(xiàng)目失敗"。谷歌和 Carbon 項(xiàng)目的文化中是否有一個(gè)類似的目標(biāo)?人們似乎把谷歌看作是一家嘗試許多產(chǎn)品并在一段時(shí)間后關(guān)閉它們的公司。例如,如下圖,Victor Zverovich 的一條推特,他利用這種看法開了一個(gè)關(guān)于 Carbon 的玩笑。考慮到 Chandler 還宣布谷歌有一個(gè)不同的團(tuán)隊(duì)有同樣的目標(biāo),但他們從 Rus t開始,轉(zhuǎn)向 C++ 后,這種思路可能并不太牽強(qiáng)。
Lucian Radu Teodorescu 表示文化是好的,Chandler 提出的觀點(diǎn)也是好的。但是,想要說服一名工程師則需要可驗(yàn)證的論據(jù)。
治理模式
關(guān)于 Carbon 公告的一個(gè)有趣之處是治理模式。Carbon 項(xiàng)目的目標(biāo)是實(shí)現(xiàn)一種沒有任何公司能決定語言未來的治理。每個(gè)人都可以通過創(chuàng)建拉動(dòng)請求來參與語言的發(fā)展,但越是重要的功能,就越需要分析/論證。
對于沒有達(dá)成共識(shí)的重要功能,有一個(gè)由三名成員(Chandler Carruth, Kate Gregory, Richard Smith)組成的指導(dǎo)委員會(huì),負(fù)責(zé)達(dá)成決定。他們沒有機(jī)會(huì)對設(shè)計(jì)做出貢獻(xiàn);他們只需要權(quán)衡提交給他們的論據(jù)并做出選擇。
有趣的是,這個(gè)模型試圖強(qiáng)調(diào)一個(gè)民主的過程,這在某種程度上類似于 ISO 的目標(biāo)。這只是對參與各方的不同劃分,當(dāng)陷入僵局時(shí)會(huì)有更明確的規(guī)則來做什么。如果從事 C++ 標(biāo)準(zhǔn)化工作的人也從事 Carbon 的工作,那么 Carbon 的過程是否會(huì)明顯好轉(zhuǎn)就不清楚了。
雖然民主方法是目前最好的治理方式,但我們最近看到了一系列重大的政治失敗,這些失敗可能與民主的負(fù)面影響直接相關(guān)。值得一提的是,在古希臘,民主被認(rèn)為是一種糟糕的治理方式。
Cpp2
CppFront 是 Herb Sutter 在 CppCon 2022 的閉幕主題演講中宣布的一個(gè)項(xiàng)目。它是一個(gè)轉(zhuǎn)碼器,可以將 "更好的 C++",即 Cpp2,轉(zhuǎn)換為舊的 C++。雖然 CppFront / Cpp2 是今年正式宣布的,但 Herb 已經(jīng)在這個(gè)項(xiàng)目上工作了大約 7 年;每年,Herb 都會(huì)展示 Cpp2 的一小部分。
Herb 希望改進(jìn) C++(即10倍),而不是進(jìn)行增量式的改變(即10%)。他希望使 C++ 實(shí)現(xiàn) 30 年前 Stroustrup 設(shè)想的那個(gè)更簡單、更干凈的語言的老目標(biāo)。有趣的是,它采用了 Stroustrup 想改進(jìn) C 語言時(shí)相同的方法:開始一種新的語言并將代碼翻譯成以前的語言。因此,CppFront 是一個(gè)小型轉(zhuǎn)譯器,它接收 Cpp2 代碼(Herb的新語言)并輸出常規(guī)的 C++ 代碼。
Herb 還設(shè)定了一些指標(biāo),我們可以用這些指標(biāo)來評估這個(gè)實(shí)驗(yàn)是否成功。更安全50倍(也就是減少98%的CVE),更簡單10倍(減少90%的教學(xué)指導(dǎo))。預(yù)先定義指標(biāo)是一個(gè)很好的策略,能夠評估實(shí)驗(yàn)的成功;我非常喜歡這個(gè)想法。
向后兼容性和互操作性
通過放棄向后兼容性,Cpp2 可以比 C++ 更簡單。這最終允許該語言刪除那些被認(rèn)為是有害的功能,并重新審視一些被證明是次優(yōu)的設(shè)計(jì)選擇。通過放棄向后兼容性,Cpp2 最終可以解決 C++ 中幾十年積累的技術(shù)債務(wù)。
說實(shí)話,在 C++ 中優(yōu)先考慮向后兼容性優(yōu)先于語言發(fā)展并不是一個(gè)可靠的例子。每次我們?yōu)檎Z言添加一個(gè)主要的功能(例如,概念、程序、模塊等)時(shí),我們實(shí)際上是在語言中創(chuàng)造一個(gè)新的時(shí)代。新的代碼可以與舊的代碼互動(dòng),但舊代碼不能簡單地依賴用新特性編寫的新代碼。盡管 C++ 標(biāo)準(zhǔn)沒有正式提及語言時(shí)代,但是在語言中有一個(gè)底層的時(shí)代系統(tǒng),由新特性的發(fā)布所決定。
可以將 Cpp2 看作是 C++ 的一個(gè)主要新特性。在互操作性和工具方面,事情要復(fù)雜一些,但本質(zhì)是一樣的。在同一個(gè)應(yīng)用程序中,舊式 C++ 不能與 Cpp2 共存,這在技術(shù)上沒有充分的理由。
按照設(shè)計(jì),Cpp2 在語義上與 C++ 接近;這使得互操作性更容易。另一方面,這也會(huì)阻止 Cpp2 擁有與 C++ 完全不同的特性。例如,Cpp2 就很難使用 C++ 0x 式的泛型。
解決安全問題
安全性提高 50 倍的目標(biāo)聽起來令人印象深刻。如果 Cpp2 能夠?qū)崿F(xiàn)這個(gè)目標(biāo),我相信大多數(shù)語言的用戶都會(huì)感到高興。
讓我們從這個(gè)數(shù)字的角度來全面了解其影響。這意味著 98% 的 C++ 應(yīng)用程序如果被翻譯成 Cpp2 就不會(huì)再崩潰了(假設(shè)崩潰只由不安全的應(yīng)用程序產(chǎn)生)。或者說,98% 的 C++ 網(wǎng)絡(luò)應(yīng)用不會(huì)有漏洞(如果沒有其他非C++的漏洞)。這將大幅減少崩潰和安全漏洞。
這似乎好得令人難以置信。實(shí)際上,如果我們更詳細(xì)地分析,這些數(shù)字似乎太高了。
首先,如果討論安全問題,需要清楚地知道什么是安全。安全性包括:
類型安全
邊界安全
生命周期安全
初始化安全
對象訪問安全
線程安全
算術(shù)安全
Herb 在他的主題演講中提到了上述的前4個(gè)項(xiàng)目。然而,這些安全項(xiàng)目的所有方面并沒有得到解決。作為一個(gè)主要的例子,在存在原始 pointer 時(shí)不能保證生命周期安全;僅僅檢查 pointer 是遠(yuǎn)遠(yuǎn)不夠的。也沒有任何一個(gè)功能來檢測 pointer .null 的使用后刪除情況。
Cpp2,正如 CppCon 主題演講中所描述的,無法檢測到這段代碼的問題:
Herb 定義了他的安全指標(biāo),包括前四個(gè)安全組件;故意忽略其他類型的安全似乎很奇怪。尤其是如果被忽略的安全成分很重要的話。
對象訪問安全是指受對象訪問模式影響的安全規(guī)則。一般來說,這一類的不安全代碼可以轉(zhuǎn)化為類型安全、邊界安全或生命周期安全。無效迭代器的規(guī)則是這個(gè)類別中很好的例子。
線程安全是 C++ 的一個(gè)大問題,Herb 完全沒有提到。在她 2021 年的 C++ Now 演講中,Anastasia Kazakova 展示了數(shù)據(jù),顯示在 C++ 社區(qū)中,并發(fā)安全占用戶 setback 的 27%。相比之下,邊界安全問題只占 16%,使用后刪除問題占用戶 setback 的 15%。并發(fā)安全是安全性方面最大的痛點(diǎn),而這一點(diǎn)沒有在 Herb 的列表中得到體現(xiàn)。
Herb 在他的幻燈片上表示,Cpp2 獲得了 "結(jié)構(gòu)安全"。這不可能是真的。結(jié)構(gòu)安全性應(yīng)該是指語言的構(gòu)建方式總是能夠?qū)е掳踩臉?gòu)造(除非程序員真的忽略了類型系統(tǒng)并將安全性掌握在自己手中)——類似于 Val 或 Rust 的構(gòu)建方式。但 Cpp2 并沒有這樣做;它只是對一些常見的不安全行為的來源增加了更多的安全檢查。如果你看過 Dave Abrahams 和 Dimitri Racordon 的演講,以及 Sean Parent 的演講,這一點(diǎn)應(yīng)該馬上就能看出來。
這讓我相信,在安全性上提高 50 倍是不可能實(shí)現(xiàn)的目標(biāo)。
關(guān)于目標(biāo)的可衡量性?
理論上,在任何時(shí)候,我們都可以根據(jù)這些指標(biāo)來衡量進(jìn)展,可以評估這個(gè)實(shí)驗(yàn)是否成功或能否成功。
讓我們從第二個(gè)指標(biāo)開始:簡單 10 倍,就像我們需要在 C++ 書籍中教授的指導(dǎo)中衡量的那樣。在這個(gè)實(shí)驗(yàn)被證明是成功之前,人們不太可能寫關(guān)于 Cpp2 的書,但可以想象這樣一本書的內(nèi)容是什么??梢源_定哪些是我們需要教授的關(guān)于 Cpp2 的一系列概念,并且我們可以將其與我們目前正在教授的關(guān)于 C++ 的內(nèi)容清單進(jìn)行比較。因此,我們可以衡量這個(gè)指標(biāo)。
這并不像人們想象的那樣簡單。C++ 有很長的歷史;因此我們知道它的陷阱,人們在 C++ 書籍中記錄了這些陷阱。但是,Cpp2 沒有這么豐富的歷史,所以,人們總是懷疑我們不知道它的所有陷阱。然而,Cpp2 與 C++ 如此接近,我真誠地相信可以排除這些顧慮,得到一個(gè)關(guān)于簡單性的準(zhǔn)確測量。
但是,我不能對第二個(gè)指標(biāo)說同樣的話。我們?nèi)绾魏饬?CVE 和安全漏洞的百分比?首先需要有一個(gè)足夠大的 Cpp2 程序的語料庫,由大量的程序員和公司編寫。然而,為了實(shí)現(xiàn)這一點(diǎn),Cpp2 需要被認(rèn)為是一種成功——一種循環(huán)的依賴。因此,在 Herb 的演講中定義的安全度量并不是衡量實(shí)驗(yàn)成功的指標(biāo)。
在主流語言使用一段時(shí)間后,使用這個(gè)指標(biāo)來評估語言是有意義的,但不能判斷實(shí)驗(yàn)的成功。
有還是沒有 monads
在主題演講的1小時(shí)33分(以YouTube視頻為參考)中,Herb Sutter 驕傲地說:"我沒有說過一次 monads 這個(gè)詞"。然后他繼續(xù)解釋說,Cpp2 是關(guān)于我們目前在 C++ 中使用的語言理念;而不是來自其他語言的奇怪的外來術(shù)語。
雖然這句話可能會(huì)吸引 C++ 社區(qū)中以自我為中心的部分人,但我認(rèn)為它對社區(qū)的傷害要大于幫助。
首先,C++ 到處都在使用 monads。新的 C+ +23 特性可能是使用 monads 的一個(gè)已知例子,但 C++ 從根本上說是圍繞著 monads 建立的。當(dāng)我們調(diào)用可能拋出異常的函數(shù)時(shí),我們隱含地使用了 monads 。也就是說,幾乎到處都是。
其次,它在語言用戶中創(chuàng)造了一種自給自足的感覺。這樣的聲明不是向社區(qū)開放新的想法,而是傳遞了一個(gè)信息:C++ 不需要向其他語言學(xué)習(xí)。但是,該語言擁有的大量技術(shù)債務(wù),以及三種繼任語言的出現(xiàn),證明了這一點(diǎn)。
比較
下面的表中試圖提供三種語言之間的比較;C++ 也是一個(gè)基準(zhǔn)。
今年宣布的 3 種 C++ 繼任語言都被認(rèn)為是試驗(yàn)品。并沒有很好的指標(biāo)表明它們是否真的能成功地吸引足夠數(shù)量的編碼人員/代碼庫,在生產(chǎn)環(huán)境中使用它們。
看看 GitHub 上的星星數(shù)量,我們看到 Carbon 是這群人中的佼佼者,與其他兩個(gè)相比,有很大的差距。Carbon 已經(jīng)成功地在社區(qū)內(nèi)進(jìn)行了更多的炒作;對包容性的關(guān)注和治理模式可能對此有貢獻(xiàn)。
這三種語言也在它們與 C++ 的相似程度方面有所區(qū)別。正如所料,Cpp2 是三種語言中最接近 C++ 的。Carbon 似乎離 C++ 更遠(yuǎn),但使用了與 C++ 相同的基本構(gòu)件塊;在 Carbon 中,用戶的思考方式與他們在 C++ 中的方式基本相同。由于可變值語義,Val 程序員在編程時(shí)需要有一個(gè)稍微不同的思維模型,這可能使 Val 成為一種離 C++ 更遠(yuǎn)的語言。另一方面,如果我們看一下 Val 的快速定義口號(hào),特別是在默認(rèn)安全和簡單的背景下,該語言的原則似乎可以很好地轉(zhuǎn)化為 C++ 的受眾。
在這三種新的語言中,Val 是唯一一種能夠支持其安全承諾的語言。其他兩種語言試圖改變一些最不安全的操作的默認(rèn)值;目前還不清楚這是否有很大的區(qū)別。
就語言特性的一致性而言,這三種語言似乎都比 C++ 更好。但在語言的連貫性方面,改變默認(rèn)值并不能讓你走得那么遠(yuǎn)。在這里,與 Carbon 和 Cpp2 相比,Val 的方法似乎更有連貫性。
最后,我認(rèn)為在我們這樣的工程學(xué)科中很重要的一點(diǎn)是:有多少語言設(shè)計(jì)決定是由某種科學(xué)支持的?在這方面,Val 似乎是唯一有一些理論基礎(chǔ)的。這可以為其用戶提供真正的保證。
放棄還為時(shí)過早
Herb 在他的主題演講中呼吁不要放棄 C++。這是一個(gè)來自 C++ 的領(lǐng)導(dǎo)層的證明,人們正在考慮放棄 C++。在一年內(nèi)出現(xiàn)了三種 C++ 的繼任語言,正好證實(shí)了這一想法。C++ 是否開始默默無聞還不得而知,但我們大概可以認(rèn)為,今年是 C++ 未來的一個(gè)拐點(diǎn)。
目前,要判斷這些實(shí)驗(yàn)是否會(huì)成功還為時(shí)過早。所有的語言都有優(yōu)點(diǎn),也都有弱點(diǎn)。如果其中至少有一種成功了,我相信我們會(huì)推進(jìn)編程語言的實(shí)踐;這可能意味著在整個(gè)軟件行業(yè)的積極影響。
在這次比較中,盡可能地保持了客觀,但我確實(shí)有自己的偏見。我希望這些偏見不會(huì)妨礙在比較這些語言時(shí)做得很好。
說到偏見,我確實(shí)需要承認(rèn):在業(yè)余時(shí)間,我已經(jīng)開始與 Val 團(tuán)隊(duì)合作,推動(dòng)語言的核心理念。對我來說,這些想法,如果能在實(shí)踐中得到完善和成功采用,比特定的語言更重要。如果 Val 作為一種編程語言消亡了,但它的所有想法都被納入了 C++,那么我會(huì)很高興。
自從我看到 Dave 和 Dimitri 在 C++ Now 上的演講錄音后,我就被可變值語義的思想所吸引。在 2022 年的 CppCon 上,我見到了 Dave 和 Dimitri,并和他們一起探討了一些細(xì)節(jié),使我相信 Val 背后的想法是深刻的,經(jīng)過深思熟慮的,值得密切關(guān)注。
看一下流行的數(shù)字,Val 的表現(xiàn)并不那么好。可能其中一個(gè)原因是,好的想法需要時(shí)間來沉淀。套用一個(gè)著名的演講,我選擇為 Val 工作,不是因?yàn)樗菀祝且驗(yàn)樗щy;因?yàn)?Val 的目標(biāo)是值得的。
引用:
[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.