采訪 | Tim Anderson
整理 | 云昭
出品 | 51CTO技術(shù)棧(微信號(hào):blog51cto)
上周,5月6-7日,于慕尼黑舉行的Qt World Summit大會(huì)上,C++之父Bjarne Stroustrup在其《21世紀(jì)的C++》主題演講前特別接受了外媒DevClass的專(zhuān)訪,訪談中涉及到很多,比如:
如何寫(xiě)出現(xiàn)代風(fēng)格的C++?為什么替代這門(mén)語(yǔ)言很難?AI潛在的風(fēng)險(xiǎn),以及為何擁有多套略有差異的編譯器反而是一件好事?等等。
盡管演講題目如此,Stroustrup并未將重點(diǎn)放在C++26(下一個(gè)主要版本)即將到來(lái)的特性上,比如反射和契約(contracts)。
圖片
他說(shuō):“這門(mén)語(yǔ)言并不只是最近新加進(jìn)去的功能而已。要寫(xiě)出符合當(dāng)代的C++,你得把從語(yǔ)言誕生早期到現(xiàn)代的各種特性組合起來(lái)使用……我最主要想說(shuō)的并不是‘有幾個(gè)特別棒的新特性你一定要用’,而是‘你應(yīng)該用好現(xiàn)在這門(mén)語(yǔ)言本來(lái)的樣子’。它現(xiàn)在是一個(gè)更加連貫的整體,更高效、更具表現(xiàn)力、更安全。”
C++程序員應(yīng)該用哪些特性,才能寫(xiě)出‘現(xiàn)代風(fēng)格’的代碼?
Stroustrup說(shuō):“很多關(guān)鍵點(diǎn)在于這些特性是如何相互配合的。我一直在努力讓程序員能用語(yǔ)言本身更直接地表達(dá)意圖。比如寫(xiě)循環(huán),現(xiàn)在95%到99%的循環(huán)場(chǎng)景其實(shí)都是‘對(duì)這個(gè)容器里的所有元素做點(diǎn)什么’,根本不用手動(dòng)定義循環(huán)變量。你可以寫(xiě)成‘for x in y’或類(lèi)似的結(jié)構(gòu),直接表達(dá)你要做的事情。這樣編譯器更容易優(yōu)化,程序員犯錯(cuò)的概率也更低,代碼也更簡(jiǎn)潔。”
他還提到范型編程:“類(lèi)型通常是可以自動(dòng)推導(dǎo)出來(lái)的,所以你總能得到正確的類(lèi)型。”
另一個(gè)至關(guān)重要的點(diǎn)是資源管理。他說(shuō):“如果你用RTTI(運(yùn)行時(shí)類(lèi)型識(shí)別)來(lái)確保資源被正確釋放,比如對(duì)象被銷(xiāo)毀、文件被關(guān)閉等等,你需要有作用域來(lái)承載這些資源。所以,所有資源都應(yīng)該由一個(gè)句柄(handle)來(lái)管理,句柄本身存在于作用域內(nèi)。這樣,絕大多數(shù)內(nèi)存泄漏問(wèn)題就不見(jiàn)了。”
現(xiàn)代C++開(kāi)發(fā)者有哪些做法是千萬(wàn)不能做的?
“千萬(wàn)不要把裸指針當(dāng)作資源句柄來(lái)用。”他說(shuō),“如果這么做,就完全違背了我剛剛說(shuō)的原則。也絕不要用單個(gè)裸指針去傳遞一組元素,比如指針指向數(shù)組。你根本不知道數(shù)組里有多少個(gè)元素,也無(wú)法做合理的范圍檢查。但如果你傳遞的是vector,它自己就知道自己有多少元素、是什么類(lèi)型。”
“另外,我?guī)缀踉僖膊挥脧?qiáng)制類(lèi)型轉(zhuǎn)換(cast)了。范型編程的好處就在這里。不用類(lèi)型轉(zhuǎn)換,類(lèi)型錯(cuò)誤的風(fēng)險(xiǎn)就大大降低。”
“以前要從函數(shù)里返回一大堆數(shù)據(jù),通常做法是放到動(dòng)態(tài)內(nèi)存里,再把指針?lè)祷兀缓筮€得記得手動(dòng)delete。現(xiàn)在,直接把一個(gè)vector move出來(lái)就行,基本是零開(kāi)銷(xiāo)。”
在演講中,Stroustrup還強(qiáng)調(diào)了模塊(modules)。用import語(yǔ)句來(lái)代替?zhèn)鹘y(tǒng)的#include。因?yàn)?include是傳遞性的,順序會(huì)影響編譯結(jié)果,而且會(huì)導(dǎo)致重復(fù)編譯和一些隱晦的bug。而import沒(méi)有傳遞性,編譯也能一次性完成,大大提高效率。
他特別提到的其他特性還包括模板(templates)和概念(concepts)(C++20強(qiáng)制支持的標(biāo)準(zhǔn)特性)。他PPT上的一句話是:“用概念其實(shí)比不用更簡(jiǎn)單。”他說(shuō),自己的生產(chǎn)環(huán)境代碼也沒(méi)有用什么比本次演講里更復(fù)雜的特性,而且基本測(cè)試通過(guò)之后,已經(jīng)很多年沒(méi)有再遇到過(guò)資源泄漏。
如何強(qiáng)制團(tuán)隊(duì)寫(xiě)出符合現(xiàn)代C++風(fēng)格的代碼呢?
Stroustrup承認(rèn)這是個(gè)難題:“在大型代碼庫(kù)里,光靠手冊(cè)式的編碼規(guī)范根本行不通。我們需要工具支持。所以我正在做一套‘profiles’,可以根據(jù)設(shè)定好的規(guī)范來(lái)強(qiáng)制檢查。”
不過(guò)他也直言,這個(gè)機(jī)制目前還沒(méi)有被C++標(biāo)準(zhǔn)采納,短期內(nèi)也不太可能:“很遺憾,標(biāo)準(zhǔn)委員會(huì)這件事上有點(diǎn)迷糊,沒(méi)能保證C++26里會(huì)加入。”
現(xiàn)在開(kāi)發(fā)者可以用Clang-Tidy之類(lèi)的工具來(lái)輔助檢查。“它已經(jīng)實(shí)現(xiàn)了我稱(chēng)之為‘C++核心指南(C++ Core Guidelines)’的一部分檢查功能,這是我跟Red Hat、微軟等公司聯(lián)合做的項(xiàng)目。”
他是否擔(dān)心AI對(duì)C++開(kāi)發(fā)的影響?
“是的,我確實(shí)很擔(dān)心。不是說(shuō)AI沒(méi)用,但它往往會(huì)把大家引導(dǎo)到以前人們常用但其實(shí)不好的做法上。更糟糕的是,我擔(dān)心人們會(huì)因此失去主動(dòng)發(fā)現(xiàn)問(wèn)題的能力,因?yàn)榇蠹叶剂?xí)慣于讓AI幫你搞定。”
像谷歌Carbon這樣的新語(yǔ)言,會(huì)取代C++嗎?
他說(shuō):“如果你只針對(duì)一個(gè)小場(chǎng)景,要做出比C++更好的語(yǔ)言其實(shí)很容易。但C++的優(yōu)勢(shì)就在于它能同時(shí)適用于非常多樣化的領(lǐng)域。再說(shuō)了,就算這些語(yǔ)言成功了,它們也必須跟C++、Python這些語(yǔ)言互操作。如果我們不小心,最后可能不是一個(gè)‘過(guò)于龐大的C++’,而是‘十個(gè)都不完整、還互相勉強(qiáng)兼容的小語(yǔ)言’。”
C++演進(jìn)是不是太慢了?
“你判斷是不是節(jié)奏合適的方法就是,看是不是有一半人覺(jué)得太慢,一半人又說(shuō)太快。”Stroustrup笑說(shuō),“是的,我確實(shí)希望比標(biāo)準(zhǔn)委員會(huì)稍微快點(diǎn)。但標(biāo)準(zhǔn)委員會(huì)太龐大了,大家關(guān)注的點(diǎn)太多,這會(huì)拖慢節(jié)奏……不過(guò),我估計(jì)更多C++程序員其實(shí)是覺(jué)得‘太快了’。”
不同C++編譯器實(shí)現(xiàn)標(biāo)準(zhǔn)的細(xì)節(jié)差異,會(huì)不會(huì)給開(kāi)發(fā)者帶來(lái)麻煩?
“是的,但你要知道,每個(gè)主流編譯器,甚至每個(gè)非主流的嵌入式編譯器,用戶數(shù)量可能都比大多數(shù)語(yǔ)言多。而且,我很討厭‘單一生態(tài)(monoculture)’。如果歷史告訴我們什么,那就是一旦出現(xiàn)單一生態(tài),一個(gè)bug或一個(gè)毒點(diǎn),整個(gè)生態(tài)就完了。”
他說(shuō),雖然主流C++編譯器彼此實(shí)現(xiàn)不完全一致,但它們彼此之間差距其實(shí)已經(jīng)越來(lái)越小了。“如果只有一個(gè)實(shí)現(xiàn),當(dāng)然有些好處,但那就是單一生態(tài)。而多個(gè)實(shí)現(xiàn)就能帶來(lái)競(jìng)爭(zhēng)空間,也有利于創(chuàng)新。它們不可能完全一致——事實(shí)上,至今沒(méi)有任何一個(gè)C編譯器是100%標(biāo)準(zhǔn)兼容的,從來(lái)沒(méi)有過(guò)。”




















