撰稿丨云昭、千山
自去年年底,美國(guó)安全局(NSA)在其所發(fā)布的《Software Memory Safety》報(bào)告中點(diǎn)名批評(píng)C++之后,C++之父Bjarne Stroustrup一頓回懟后,做出決定:內(nèi)部自救。現(xiàn)在,就讓我們看看下一個(gè)版本的C++,究竟有哪些大動(dòng)作!
1、三年一版本,26版時(shí)間表已定
ISO C++標(biāo)準(zhǔn)委員會(huì)主席、微軟原生語(yǔ)言架構(gòu)師Herb Sutter,6月16日發(fā)布了關(guān)于C++26的進(jìn)展,承諾“將發(fā)布一個(gè)巨大的并發(fā)和并行版本”以及其他變化。
C++版本按發(fā)布年份命名,并遵循3年一個(gè)版本周期。該委員會(huì)在保加利亞瓦爾納舉行了在線會(huì)議,有近180名成員,并正式通過了C++26的時(shí)間表。
薩特表示,該時(shí)間表“與C++23的時(shí)間表相同,只是各個(gè)節(jié)點(diǎn)處向后加了三年”。時(shí)間表顯示,“以前從未見過”的新語(yǔ)言功能的最后日期是2024年第三季度,功能凍結(jié)的節(jié)點(diǎn)是在2025年第一季度。(PS:C++23的功能凍結(jié)是在2022年第一季度。)
值得注意的是:功能凍結(jié)并不意味著2026年停止開發(fā)新版本,而是暫停將新功能加載到這個(gè)特定序列中的檢查點(diǎn)。一般而言,第三年是一些繁瑣的錯(cuò)誤修復(fù)的一年。
2、核心變更一覽
薩特說,委員會(huì)通過了40份“變更文件”。這其中,有兩份是“為所有就緒問題”提出的應(yīng)用解決方案,其余38份都是單獨(dú)的更改(如錯(cuò)誤修復(fù)、新功能等)。
目前為止提出的新功能大都比較低調(diào)。比如:添加了對(duì)_字符作為通配符的支持,并將@、$和`添加到基本字符集(就像對(duì)C23所做的那樣)。
舉個(gè)例子:編譯器開始支持draft-C++26語(yǔ)法:
std::lock_guard_(mutex);
auto [x,y,_]=f();
inspect(foo){_=>bar;};
標(biāo)準(zhǔn)庫(kù)更改
- 添加了“function_ref”類型可擦除的可調(diào)用引用
- 添加“格式化指針”允許對(duì)指針值進(jìn)行漂亮的格式化,而無(wú)需reinterpret_cast首先轉(zhuǎn)換為整數(shù)類型。例如,現(xiàn)在可以這樣用:format("{:P}", ptr)
- 添加“constexpr”允許編譯時(shí)使用標(biāo)準(zhǔn)庫(kù)的穩(wěn)定排序等。
“格式化指針”允許對(duì)指針值進(jìn)行漂亮的格式化,而無(wú)需reinterpret_cast首先轉(zhuǎn)換為整數(shù)類型。例如,這現(xiàn)在可以工作了:format("{:P}", ptr);
3、Hazard Pointer:C++26新增“危險(xiǎn)指針”
危險(xiǎn)指針是“只有危險(xiǎn)指針的所有者才能設(shè)置其值,而任何數(shù)量的線程都可以讀取其值”的指針。
危險(xiǎn)指針是一個(gè)單寫多讀指針,在任何時(shí)候最多可由一個(gè)線程擁有。只有危險(xiǎn)指針的所有者可以設(shè)置其值,而任何數(shù)量的線程都可以讀取其值。所有者線程將危險(xiǎn)指針的值設(shè)置為指向某個(gè)對(duì)象,以便向可能刪除該對(duì)象的并發(fā)線程指示該對(duì)象尚未安全刪除。
不過,這對(duì)C++安全來說都不是一場(chǎng)革命。Hacker News的一位開發(fā)人員表示:“如果你正在編寫無(wú)鎖并發(fā)數(shù)據(jù)結(jié)構(gòu),并且你需要一種方法來處理節(jié)點(diǎn)刪除后的延遲回收,那么危險(xiǎn)指針很重要。這是一個(gè)非常奇怪的問題,很難成為‘內(nèi)存安全問題的常見來源’。
另一位開發(fā)者進(jìn)行了補(bǔ)充:“在迭代器中使用,這是危險(xiǎn)指針的用例之一。危險(xiǎn)指針可以在不令已有迭代器失效的情況下改變hashmap的key,雖然它適用于多線程,但如果寫入和讀取恰好在統(tǒng)一線程上,一樣有效?!?/p>
Sutter表示,“并發(fā)和并行子組仍在推進(jìn)C++26的std::execution和SIMD并行”,這將是并發(fā)編程的重要功能。
4、后來者帶來的壓力
相較于Sutter對(duì)于C++標(biāo)準(zhǔn)的穩(wěn)步發(fā)展的熱情,編程領(lǐng)域內(nèi)對(duì)于新語(yǔ)言的呼聲卻越來越高。前不久,微軟首席技術(shù)官M(fèi)ark Russinovich宣布,“是時(shí)候停止用C/C++啟動(dòng)任何新項(xiàng)目,并在需要非GC語(yǔ)言的情況下使用Rust了。為了安全和可靠性,行業(yè)應(yīng)該宣布這些語(yǔ)言不受歡迎?!?/p>
除了Rust,C++的另一個(gè)潛在競(jìng)爭(zhēng)對(duì)手是谷歌的實(shí)驗(yàn)性項(xiàng)目:Carbon;甚至就連Sutter自己,也提出了實(shí)驗(yàn)性的cppfront,他說:“我的目標(biāo)是探索是否有一種方法,可以使C++變得更簡(jiǎn)單、更安全、更可工具化10倍!”cppfrond語(yǔ)言由Sutter于2022年底在CppCon上提出。
然而,新語(yǔ)言的一個(gè)問題是大量的現(xiàn)有代碼永遠(yuǎn)不會(huì)被移植,這意味著改進(jìn)C++仍然是值得的,即使對(duì)于那些認(rèn)為它有固有缺陷或過于復(fù)雜的人來說也是如此。
5、越來越不像C++了
對(duì)于一門上世紀(jì)誕生的骨灰級(jí)編程語(yǔ)言來說,C++可謂非常成功。然而,許多C++愛好者中,流行一種說法:C++11以后,C++也越來越不像C++了。它完全是一門新的語(yǔ)言。
C++活生生把自己變成了一個(gè)筐,缺啥東西都得裝。網(wǎng)友抱怨:明明是一個(gè)聚焦底層的語(yǔ)言,為什么很多人幻想在標(biāo)準(zhǔn)庫(kù)里放各種迎合千奇百怪需求的上層庫(kù)呢?
與其這樣,還不如多關(guān)注C++本身底層的改進(jìn),好好維護(hù)發(fā)展庫(kù)生態(tài)。
截圖:知乎
此外,C++社區(qū)分裂,缺少統(tǒng)一標(biāo)準(zhǔn),也是其近些年一直被詬病的地方。Windows陣營(yíng)、谷歌陣營(yíng)、QT陣營(yíng)彼此割裂導(dǎo)致移植性不會(huì)像Java、Go那樣子絲滑。
截圖:知乎
6、寫在最后
誠(chéng)然,許多新語(yǔ)言都踩在舊語(yǔ)言的肩膀上,而且是從舊語(yǔ)言犯過的錯(cuò)誤中汲取養(yǎng)料,茁壯起來。Rust從C++中學(xué)到了內(nèi)存安全的重要性,Zig從C中選擇了更細(xì)分的內(nèi)存分配,Go則帶上“指針”和“垃圾收集”兩件法寶自成一派。
而C++曾經(jīng)也是一位昂揚(yáng)向上的少年,只不過經(jīng)歷了40年之久的他,已經(jīng)無(wú)須證明自己有多么成功?,F(xiàn)在C++很清醒:它已經(jīng)是一個(gè)老語(yǔ)種,身上的包袱很重,更需要穩(wěn)定地負(fù)責(zé)任地承載著過去的版本,同時(shí)一路吸收著后來的其他語(yǔ)言“小弟”們創(chuàng)新點(diǎn),慢慢前行。
參考鏈接:https://devclass.com/2023/06/19/c-26-is-already-taking-shape-says-herb-sutter/