![]()
來源:InfoQ
編譯:宇琪
策劃:Tina
“我已經看到一些高級開發者開始退休了——因為他們不想再處理這種驗證工作:你每次改代碼、改提示詞,生成出來的東西都會變。”75 歲的 C++ 之父 Bjarne Stroustrup,在最新一期播客里說了這段話。
這句話很快在 X 上被轉發、放大。有人把它濃縮成一句更適合傳播的話:
“資深開發人員寧愿退休,也不愿處理 AI 生成的代碼。”
![]()
嚴格說,這不是 Stroustrup 的原話。但它確實抓住了這段討論里最讓開發者有感觸的部分:AI 寫代碼的爭議,已經不只是“它能不能生成代碼”,而是生成之后誰來驗證、誰來理解、誰來承擔系統長期運行的后果。
有網友評論說,Stroustrup 寫系統代碼的時間,比大多數 AI 工程師活過的時間還長。當他說“驗證才是真正的問題”時,這并不是對變化的抵觸,而是幾十年來一次次看到系統出錯、卻無法追蹤問題源頭之后留下的經驗。
“AI 生成的代碼更臃腫,有更多 bug 和安全漏洞,而且很難驗證。” Stroustrup 還指出,LLM 用舊代碼訓練,生成的代碼在“模仿舊代碼,得到舊的性能和舊的 bug”。
這期節目并不只談 AI。Stroustrup 還系統回顧了他的職業生涯以及 C++ 四十余年的演進脈絡,編程語言的設計哲學、C++ 標準化歷程。
他直言 90% 以上的內存安全漏洞并非 C++ 語言本身的缺陷,而是“人們寫的是 C 風格代碼”;他透露 C++ 的市場營銷預算是三年 5000 美元,而 Java 的營銷投入“比 C++ 整個開發費用還多”;他回憶自己如何在 IBM 和 Intel 的工程師之間來回穿梭調解,最終促成一個被納入 C++11 標準的技術妥協,而多年后雙方都承認,他們實際使用的是雙方方案的組合……基于該視頻,InfoQ 對內容進行了整理與部分刪改。
核心觀點如下:
![]()
C++ 的起源故事
Ryan:C++ 的起源故事是什么?
![]()
但我學過 Simula,我認識發明了面向對象編程和 Simula 的 Christian Nygaard 和 Ole Johan Dahl,所以我決定把這兩者融合起來。
可行的方式是把 Simula 中的類(class)概念拿過來,嵌入到 C 語言中,讓它運行得更快,并用于系統編程。同時,我讓類型系統變得更規整,用戶定義類型與內置類型的處理方式完全一致。后來,為了支持泛型編程,我又必須添加重載(overloading),我需要把這種規則推廣到用戶定義類型和內置類型都適用。這就是 C++ 的起點。
Ryan:在你的一次講座中,你提到用 BCPL 重寫了一個模擬器,那是分布式 Unix 的工作嗎?
![]()
但一旦完成,我的程序運行速度估計快了大約 50 倍。我拿到了數據,拿到了博士學位。但我也堅信:我再也不會用那么不稱手的工具去解決一個問題了。所以我列出了一份理想語言應該具備的特性清單,C++ 沒有包含全部,但它比任何其他現存語言都更接近,C++ 就是從那里誕生的。
Ryan:在那次講座中,你說用 BCPL 寫那個程序太難了,你因此掉了一半的頭發。
Bjarne:幾乎完全正確。后來我為了把 C++ 做起來,又掉了另一半。但不管怎樣,它成功了。
傳奇的貝爾實驗室
Ryan:你提到了貝爾實驗室,那是個傳奇的地方。很多人對它充滿好奇。當你博士畢業、考慮去哪里工作時,貝爾實驗室在當時是個什么樣的存在?
![]()
Ryan:面試過程是什么樣的?
![]()
Ryan:你哪來的信心自費飛過去?連工作都沒保證。
![]()
Ryan:像貝爾實驗室這樣的地方,項目選擇是怎么運作的?你入職之后,他們怎么決定你做什么?
![]()
C 語言之父與胖指針
Ryan:我聽說你每周和 Dennis Ritchie 吃一次午飯,持續了 16 年?他對你有什么影響嗎?
![]()
Ryan:你寫過三篇很長的 C++ 歷史論文,里面提到 Dennis Ritchie 向 C 標準委員會提過一個“胖指針”的概念——指針里同時存儲大小,但 C 委員會沒批準。能講講這個故事嗎?
![]()
Ryan:當你把一群真正令人印象深刻的人聚在一起,其他人的卓越會讓人產生一種冒名頂替綜合征的感覺,你曾經感受過或目睹過這種情況嗎?
![]()
語言設計哲學
Ryan:說到語言設計,如果今天有人想從頭構建一門編程語言,需要準備哪些東西?
![]()
![]()
Ryan:當你發現問題后,開始構建 C++ 時,有很多組件——編譯器、鏈接器、解析器、詞法分析器等等。在最初實現中,哪部分技術挑戰最大?
![]()
Ryan:我注意到 C++ 工具鏈的某些部分是用 C++ 本身寫的,這就有個雞生蛋蛋生雞的問題。怎么做到的?
![]()
Ryan:很多人以為 C++ 是純面向對象語言,但你反復強調不是這樣。
![]()
Ryan:你在設計 C++ 時,C 已經存在,而它的類型系統比 C++ 弱得多。為什么你選擇讓 C++ 的類型系統更強?
![]()
Ryan:C++ 是有名的靜態類型語言,為什么你選擇了靜態類型?
![]()
Ryan:你剛才提到內存受限的問題,這讓我想到靜態類型和動態類型的另一個維度——開發效率。對于普通開發者來說,哪種方式更省時間?
![]()
Ryan:說到保證,C++ 在內存安全問題上名聲可不太好,那些“自爆開關”(foot guns)讓很多人頭疼。
![]()
Ryan:有沒有辦法讓編譯器直接阻止人們做那些危險的事?這在現代 C++ 里默認開啟了嗎?
![]()
C++ 標準化歷程
Ryan:標準委員會是一個有趣的話題,語言由一個民主機構管理。如果它是一個獨裁體制,你一個人說了算,你會加入哪些語言特性?
![]()
Ryan:如果你當時堅決說“不”呢?會發生什么?
![]()
Ryan:光看采用率的話,C++ 顯然比 Java 高得多。可我知道 Java 背后有大公司撐腰,砸了那么多營銷的錢,而 C++ 呢,我記得你好像說過它的營銷投入幾乎為零。
![]()
Ryan:規則里寫的最低底線是多少?
![]()
Ryan:民主決策是不是總得有點客觀規則才行,萬一召集人判斷錯了怎么辦?
![]()
Ryan:你曾說過你提過的所有想法里,被懟得最慘的之一就是 auto。我知道 auto 后來還是進了標準,但當時它為什么那么不受待見?
![]()
Ryan:我還聽說委員會內部有時會激烈爭吵,比如你做過“穿梭外交”,在 IBM 和 Intel 的兩撥人之間來回調解。
![]()
Ryan:1995 年你曾提議在 C++ 中引入某種形式的自動垃圾回收(garbege cllector)。這讓我很驚訝,因為 C++ 沒有垃圾回收器,我們得自己手動管理內存,這到底是怎么回事?
![]()
Ryan:那個標準接口是怎么工作的?是對內存分配方法做了一層包裝?
Bjarne:對。你對底層的`new`、`malloc`或`operator new`做不同的實現,然后`delete`也變得稍微不同。
不要在脆弱的根基上堆砌功能
Ryan:C++ 社區里有一個關于“瓦薩號”戰艦的警示故事。為什么它這么流行?
![]()
Ryan:有人證明 C++ 模板實例化機制是圖靈完備的。編譯器在預處理 C++ 程序時,實際上可以用它來做計算,比如有人用它在編譯時計算素數。這怎么做到的?
![]()
Ryan:一般來說,大家對編程語言有個直覺:你離機器越近,性能就越高。我常聽人說,C 比 C++ 更貼近機器。
![]()
Ryan:你好像在哪說過 C++ 可以比 C 性能更高,但我總覺得更多的抽象總得付出點代價吧。
Bjarne:它在編譯時被優化掉了。這就是我所說的“零開銷抽象”。現在有人開始批評我,說這個說法低估了 C++ 編譯器的能力——我們可以實現“負開銷抽象”。
Ryan:如果我是一個匯編高手,有無限的時間,那比起來怎么樣?
![]()
我跟一個在西班牙做流體動力學的朋友合寫了一篇論文,我們拿一個性能測試套件里的真實例子,把那些聰明玩意兒全扔了,結果代碼量減少到原來的百分之八十,性能反而提升了百分之二十。你只在需要的時候才做優化。Knuth 說,不要過早優化,但他也指出,只有那百分之二到三的地方才值得去優化。所以,先用高層次設施把東西搭起來,看看夠不夠好;如果不夠,你必須去測量時間,找出時間都花在哪兒了,最后再優化那部分。但很多時候,你根本走不到那一步,它已經足夠快了。
Ryan:你說的“聰明”,是指靠人工手動管理去榨取性能,而你的意思是,如果不去做這些,編譯器反而能得到更多信息去優化,而且它現在干得遠比以前好。
Bjarne:那些在九十年代被精巧而正確地優化過的代碼,放到今天常常變成劣化,因為機器架構變了,編譯器也進步了。
AI 寫代碼越多,高級工程師越不想接盤
Ryan:如果越來越多的代碼是由模型和機器寫的,你覺得編程語言設計會跟著變嗎?
![]()
![]()
當然,也許你可以改進它。我聽說有人在寫 Bjarne app,喂給它我的文章,但就算那樣也有問題,因為我現在說的東西,并不完全等同于我 20 年前說的東西。
不過不管怎樣,我們會看到結果的。嗯,甚至 Dijkstra 也研究過這種可能性,他當時聲稱,把自然語言當成編程語言的想法是愚蠢的。他沒有我這么客氣。
我的看法是,像英語這樣的語言非常靈活,我們說的話往往非常含糊。但我們需要的是一種精確的編程語言,那是工程,是數學,不是英語。
Ryan:對于那些性能攸關或安全攸關的代碼,我猜還是會有一小群人嘗試用 LLM 去弄。按你說的,那會導致更多的崩潰和 bug,因為它是沒經過驗證的。
![]()
給初學者的建議與反思
Ryan:有人問你是什么支撐你一直搞 C++,你說,一是構建未來的那種樂趣,二是覺得自己有義務確保 C++ 不斷前進。當你剛開始做 C++ 的時候,我很難想象你知道自己會踏上一條長達幾十年的旅程。
Bjarne:倒不是幾十年,但我知道這會是條很長的路,因為我知道我沒法一步到位造出我想要的語言,只能先造一個子集。原因有兩個:第一,我是一個人在做這件事;第二,我缺少足夠的反饋輸入,來確保我設計的東西是對的。這就是工程上的問題了:盡你所能去建造,看看什么管用,然后再改進。所以我知道我在創建一門注定要持續演進的語言,而“注定要演進”意味著,你在做某些決定的時候,就已經知道這一點跟別的不一樣。舉個例子,這也是 C++ 不只是一個面向對象編程語言的原因之一,因為我當時看到了很多東西,似乎無法塞進那個范式里,所以我知道我們會演進。
支撐我走下去的另一半答案,是那些應用。看到那些有趣的用法,感覺真是太棒了。比如我去噴氣推進實驗室,跟搞火星車的人聊天,我還去過歐洲核子研究中心,去看他們怎么搞高能物理的。幾年前,我跟一個哥們兒聊天,他的工作是開門和關門。那些門有幾噸重,是鉛做的,會橫向移動,去封閉某個區域以防輻射什么的。啟動這扇門倒不難,有引擎。但他必須確保能把它停住,因為當幾噸重的家伙向一堵墻移動時,它可不會自己乖乖停下。他得寫代碼來處理這個,那段代碼非常有意思。我至今仍在到處旅行,跟人聊天,看 C++ 正在被用在什么地方,這也是學習,而學習本身就很有趣。
Ryan:你有一個著名的比喻:C 讓你容易射中自己的腳,C++ 讓你更難射中,但一旦射中,整條腿都沒了。
Bjarne:對,這來自我 80 年代在波士頓的一次演講。Arnold Penzias(諾貝爾物理學獎得主)曾試圖向一群貝爾實驗室的經理解釋 C++。他說:“你不能在不了解如何使用的情況下使用電動工具,你用手鋸,可以這么來回鋸。可你要換了把電鋸還這么干,它會直接彈起來,你要是不受傷那就算走大運了。”背后的意思就是,你拿到一件更強大的工具,卻用錯了方法,惹出的麻煩只會更大。
Ryan:你還有一句名言:“沒有人應該自稱專業人士,如果他們只懂一門語言。”你顯然會建議大家學 C++,但如果他們為了成為更好的工程師或程序員,必須再學一門第二甚至第三語言,你會推薦什么?
Bjarne:重要的不是學哪些語言,而是獲得那些語言中蘊含的思想,你應該學和你當前語言不同的語言。具體挑哪種,我其實不太糾結。我當時好像說去學一門腳本語言,今天可能是 Python 或 JavaScript,在那時候大概是 Unix Shell 之類的。再看看一門函數式語言,ML 或 Haskell 是明顯的選擇。關鍵是不要只局限在你的語言里。就像那個笑話:懂三種語言的人叫“三語者”,懂兩種語言叫“雙語者”,懂一種語言叫“美國人”。編程語言也一樣,但我覺得編程語言更重要,因為你是在構建東西,你應該用不同的思想和技術來拓寬你的視野。
Ryan:還有一個:“那些自以為無所不知的人,真的很煩我們這些自知一無所知的人。”
Bjarne:有太多人認為世界上所有事情都有簡單的解決方案。在這個語境下,他們會來告訴我 C++ 可以簡單多少。確實,如果你只想做一件事,你可以做一門簡單得多的語言。如果你扔掉 C++ 的一部分,它會更簡單、更漂亮,通常他們想扔掉的是跟 C 兼容的部分。但那樣你會惹惱幾百萬人,而且不會成功,因為他們會繼續抱著舊東西不放。所以,這不過是我對那些過度簡化事物的人表達挫敗感的一種方式罷了。有些人覺得不用學編程就能寫程序,不用學工程學就能當工程師,不用懂怎么管理公司或國家就能當政客,這種過度簡化讓我惱火。
Ryan:你說過 C++ 不是為所有人設計的,而是為嚴肅的程序員準備的。
Bjarne:對。《C++ 程序設計語言》第一版的第一行是:“C++ 旨在讓嚴肅程序員的生活更愉快。”第一版是的用詞是“專業程序員”,后來改掉了,因為我見過非常優秀的業余愛好者。“嚴肅程序員”大概是為別人編程的人。如果你為自己編程,沒關系,那是你自己的問題。如果你為朋友編程,你可能會失去朋友。如果你為一百萬人構建東西,你可能會對世界造成傷害。Guido van Rossum 設計 Python 的明確目標是讓更多人,甚至每個人都能編程,他成功了。我設計 C++ 是為了給嚴肅的程序員、工程師、數學家,提供真正好的工具,我也成功了。我們解決的是不同的問題。
Ryan:回顧 C++ 的整個旅程,有沒有什么地方你覺得是錯誤,或者學到了教訓?
Bjarne:很多很多次。但大多數錯誤從未進入 C++——這就是你需要做實驗、需要早期試用的原因。我認為語言的核心部分是對的,但每一個細節都可以改進。然而,穩定性和兼容性才是根本。你要是做個小改動,會惹毛一小部分人,影響不大;可你要是做了個大改動,你就會惹毛一大群人,而且根本行不通,因為比如會有上百萬人堅守舊的方式。所以我努力的方向是,讓這門語言在不破壞現有東西的前提下生長。
有個場景我反復遇到。人們跑來跟我說:“C++ 太復雜了,你得把它簡化。”然后緊接著又是:“我需要這兩個功能,昨天就要,你在簡化的同時,必須給我加上這兩個功能。”末了再加一句:“反正你干什么都行,千萬別破壞我的代碼,我有一百萬行呢。”這根本行不通,根本不可能。這就是為什么我現在在研究編程指南和 Profiles,也就是強制性的規則集。通過這種方式,你可以設計一個 Profile,確保你能用到你需要的庫,同時保證你不會誤用那些在你那個領域里不必要、又危險的功能。
Ryan:對于想學習 C++ 的人,你有什么技術書籍推薦?
Bjarne:有一本我教本科生時寫的書——《編程:原理與實踐(使用 C++)》。要學就用最新的 C++,先學現代的方式,別一上來就學那些糟糕的 C 語言老套路。可是很多課程還是讓你先學 C,先學`malloc`、指針之類的問題,然后才學怎么用`vector`和`string`來避免這些問題。Profiles 就是為了讓編譯器和靜態分析器支持這種思維方式,教育者也在要求類似的東西。很多人認為 Profiles 只是為了處理內存安全和性能。不,它是要給人一件更好的工具,既為了學習,也為了從事特定種類的工作。
Ryan:如果你能回到職業生涯的起點,給自己一些建議,你會說什么?
Bjarne:天吶,這是個“時間機器”問題。我有時候會給我的學生布置這道題你有一臺時間機器,回去給 Dennis 提點建議,干完這事之后,再往前跳十年,來給我一些建議。這是個很好的練習,我總能從學生那兒收到些很精彩的故事和建議。
我當時努力想避免 C 語言里內置類型之間的雙向隱式轉換,我本該在這件事上抗爭得更堅決一些。我試過,但被貝爾實驗室的人攔住了。他們比我更有經驗,諸如此類。現在我明白了,我當時應該更進一步的。
還有,我本該推遲 C++ 的發布,直到我能拿出類似模板的東西,這樣我就能做一個更好的標準庫。即便當時做出來,也不會足夠好,但它能讓人們從一開始就養成使用標準的習慣。當時人人都在造自己的標準庫,最后是 Alex Stepanov 用 STL 救了我們,但那純粹是運氣,因為我沒有推遲發布,這確實是個錯誤,我本應該等到能造出一個好的 vector 和一套類層次結構的時候。
最后,如果我能帶著現在對標準委員會和臃腫官僚體制的了解回到過去,我會非常努力地去建立一個指導小組。我們會有一個五百人的社區來貢獻提議,然后由一個大概只有五六個人、擁有深厚經驗并且關心整門語言的小組,基于這些提案來做決策。但我當時沒有那個經驗和知識去提出這樣的建議。
我沒提工具的事。C++ 在工具方面一直是個短板,那是因為它成長在一個早期時代,工具匱乏,算力有限,內存有限,所以我當時也根本做不到。我給學生們布置時間機器練習時,有一條約束是:確保你給的建議在當時是有可能被采納的。如果我只是說“我想要這個”,那么許多事情可能要到二十年之后才能做到,因此也就永遠不會發生。有很多語言是奔著“為未來的計算機和程序員而設計”去的,它們中的大多數都死了,因為十年后當它們終于面世時,世界早就變了。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.