“如果我們必須用對底層的絕對掌控來換取物理極限的性能,那么 C++ 依然是這個星球上無可替代的語言。”
嘉賓| David Sankel 采訪 | 吳詠煒
責編|夢依丹
出品 | AI 科技大本營(ID: rgznai100)
在 Rust 強勢崛起、AI 編程重塑開發范式的今天,C++ 這座歷經四十載風雨的編程大廈,似乎正面臨著前所未有的生存拷問。
內存安全漏洞是否真的無解?
AI 生成的代碼究竟是福音還是隱患?
當“未定義行為”從優化的基石變為安全的夢魘,C++ 標準委員會又將如何應對?
帶著這些尖銳而深刻的問題,在 2025 全球 C++ 及系統軟件技術大會的采訪間,奇點智能研究院首席技術咨詢師吳詠煒與 Adobe 首席科學家、C++ 標準委員會資深委員 David Sankel 展開了一場直擊痛點的深度對話。
![]()
左:吳詠煒,右: David Sankel
如有興趣觀看完整視頻,可在文末獲取
David Sankel 沒有回避任何一個敏感話題。從揭示“新代碼比舊代碼更脆弱”的反直覺真相,到坦陳 C++ 在工具鏈生態上被 Rust“降級打擊”的無奈,再到對 AI 編程助手“既依賴又懷疑”的矛盾心態,Sankel 以一位頂尖語言設計者的視野,為我們抽絲剝繭,還原了一個真實、復雜且充滿生命力的 C++ 世界。
這不僅是一場關于技術的探討,更是一次關于如何在不確定的技術浪潮中尋找確定性的思想碰撞。
以下為對話全文:
吳詠煒:嗨 David,歡迎來全球 C++ 及系統軟件技術大會的采訪間。請你先向大家打個招呼。
David Sankel:大家好。真的很高興能來到這里,感覺特別棒。
吳詠煒:首先,我們來探討一下現代代碼與遺留系統的安全性問題。你在本次大會演講中提到了一個耐人尋味的趨勢:大多數內存安全漏洞源于新編寫的代碼,而不是遺留系統。 你認為這是什么原因造成的?是因為語言固有的復雜性、對現代特性的誤用、開發者經驗不足,還是工程流程和工具鏈存在缺口?
David Sankel:這個現象的核心在于“代碼硬化”(Code Hardening)的過程,它通常只發生在那些長期承受巨大安全審查壓力的舊代碼上。
以 Zlib 這個古老的 C 語言庫為例,多年來,無數人都在積極地試圖攻破它。在這個過程中,絕大多數潛在的漏洞都已經被挖掘并修復了。只要這種對抗性的壓力持續存在,代碼就會隨著時間的推移變得越來越堅固。
漏洞出現在新代碼中的原因,實際上僅僅是因為這些代碼還沒有時間在那種對抗性壓力下經過“歷練”。這完全是關于漏洞生存周期的問題。如果你看看舊的 Zlib 代碼剛出來的時候,它也有成噸的漏洞,那時候的“遺留代碼”在當時也是“新代碼”。這似乎只是公共領域軟件的一種現象,因為人們總是在試圖攻擊它。
因此,這主要是一個成熟度的問題:代碼越成熟,Bug 自然越少。
這種現象積極的一面是,我們不需要回頭去處理所有的代碼庫。如果你拿 Adobe Photoshop 來說,它有 6800 萬行代碼,我們無法回頭去修復所有那些舊代碼。但好消息是,我們其實不必像防范新代碼那樣去焦慮舊代碼。我們將防御重點集中在新引入的代碼上,這讓內存安全問題從一個“不可能完成的任務”變成了一個“可控的工程問題”。
吳詠煒:我們知道,在 C 語言中,由于開發者通常需要直接管理定長數組和原始內存,緩沖區溢出這類問題非常普遍。理論上,C++ 引入了許多現代特性,本應大幅降低此類風險。但現實數據卻表明,我們依然面臨著大量的內存相關漏洞。為什么在機制更完善的 C++ 中,這類問題依然無法根除?
David Sankel:C++ 確實通過引入高級抽象降低了內存安全漏洞的發生頻率,但這并不意味著它從根本上消除了隱患。
現實情況是,工程師仍然很容易寫出導致越界訪問的代碼。過去是對 C 風格數組的越界,而現在的“現代版本”則是對 std::vector 的越界訪問——其本質依然是相同的內存安全問題。 再比如使用未初始化的變量,這種風險在 C++ 中也并未消失。
歸根結底,C++ 繼承了 C 語言的底層內存模型和許多“不安全”的基因。只要這些從 C 語言遺留下來的底層機制仍然被允許使用,或者現代容器的使用方式缺乏強制性的安全約束,內存安全漏洞的溫床就依然存在。
吳詠煒: 相比十年前,我們現在擁有了強大得多的動態分析工具。比如 Memory Sanitizer (MSan)、Address Sanitizer (ASan)、Thread Sanitizer (TSan) 以及 Undefined Behavior Sanitizer (UBSan) 等等
David Sankel:你說得完全正確。問題是:這些工具是否在 C++ 生態系統中被普遍使用了?遺憾的是,我認為答案是否定的。
阻礙工具普及的原因可以分為兩類。一類是主觀因素——比如開發者缺乏認知,或者根本不在乎;但更關鍵的,是一類非常現實的客觀門檻:這些工具的配置成本極高。
要想讓這套 Sanitizer 組合在構建系統中完美運行,需要付出巨大的工程代價。這往往要求你在項目啟動之初就具備極高的前瞻性,并投入資源去配置基礎設施。但在項目早期,你甚至不知道它能不能存活下去,往往無暇顧及這些。
這就導致了一個典型的“成功悖論”:等到你的開源庫大獲成功、被廣泛采用時,它可能一直是在沒有 Sanitizer 保護的“裸奔”狀態下開發的。突然之間,潛伏的漏洞隨著你的庫擴散到了整個生態鏈。
更糟糕的是,即便你現在亡羊補牢加上了防護,下游用戶依然可能在使用你的舊版本代碼。為什么?因為在 C++ 生 態中,依賴管理和版本升級是一項昂貴的工程活動。用戶往往因為升級成本過高而停留在有漏洞的舊版本上,導致問題持續存在。
吳詠煒:但我認為你的論點可能是我們不想用 C++ 寫新代碼。但其實,我們完全可以在新代碼中使用這些工具,而不是在舊代碼中,因為舊代碼可能有更多的兼容性問題。在新代碼中,我們絕對可以使用新工具。
David Sankel:你的論點建立在一個關鍵假設之上:即只要使用了這些新工具,就能解決所有、或者至少絕大部分的內存安全漏洞。 誠然,它們能大幅緩解問題,但現實數據卻給我們潑了一盆冷水。
讓我們看看 Google 的數據。在 Android 系統開發中,他們擁有世界頂級的工程師團隊,并且在 C++ 開發流程中強制啟用了所有的 Sanitizer 和最佳實踐。即便武裝到了這種程度,他們依然持續發現 C++ 代碼中的內存漏洞。
更令人震驚的對比來自于他們引入 Rust 之后的數據:在同樣的嚴苛標準下,C++ 代碼產生的內存安全漏洞數量幾乎是 Rust 代碼的 1000 倍。
這是一個非常“硬”的數據。它揭示了一個殘酷的現實:工具只能緩解癥狀,卻無法根治病灶。
如果單靠打開 Sanitizer 就能徹底解決問題,那么 Google 根本不需要大費周章去引入新語言。既然連擁有最強技術實力的 Google 都無法在 C++ 中徹底封堵這些漏洞,這本身就證明了這是一個極其艱深、甚至可能是目前范式下無解的難題。
再舉個身邊的例子,我團隊里的 Sean Parent——他是公認的 C++ 泰斗級人物——依然會踩進內存安全的坑里。有一次他在處理復雜的模板元編程時,面對層層封裝的抽象,想要搞清楚一個深埋其中的 auto&& 到底推導出來的是一個右值引用還是一個指向局部變量的懸垂引用,簡直難如登天。
吳詠煒:是的,我認為抽象是一個大問題,會讓測試 constexpr 函數變得很難……我認為模板元編程還要更難。實際上,我最近也遇到了一個這樣的問題,也是在元編程中。我實際上立即發現了問題,因為程序崩掉了。但要弄清楚問題到底在哪真的很難,因為問題隱藏得很深,而且僅在某些特殊場景里才出現。
David Sankel:對,他的情況也是一模一樣的。
吳詠煒: 好的,讓我們轉向下一個關于 C++ 價值主張的問題。如今 Rust 憑借“內存安全”特性迅速崛起,Python 在 AI 時代更是占據主導,也確實吸走了一部分原本依賴 C++ 的用戶。但在游戲引擎、系統底層、高性能計算等核心場景,C++ 依舊穩固。在你看來,C++ 最核心、最不可替代的優勢是什么?為什么這些優勢至今仍難被其他語言取代?
David Sankel:我認為 C++ 擁有一個任何人都奪不走的“利基市場”(Niche),其核心價值主張在于:它允許開發者通過承擔“未定義行為”(Undefined Behavior)的風險,來換取絕對極致的性能。
讓我用一個最近看到的對比案例來說明。有一段 C++ 代碼執行某種整數運算,這其中可能隱含著溢出或除以零的風險。但在編譯器的優化下,這段代碼被極致精簡為一條匯編指令:一個移動加一個加法。
代價是: 如果輸入數據錯誤,程序行為完全不可控(未定義)。
收益是: 如果你能保證數據正確,它就是物理上能達到的最快速度。
當開發者試圖在 Rust 中復刻這段代碼時,困難出現了。Rust 的安全機制強制要求檢查“除以零”和“整數溢出 panic”。為了讓 Rust 代碼達到和 C++ 一樣的指令級效率,開發者不得不使用大量的 unsafe 塊、特殊的編譯器提示(Hint)和注解。最終,性能確實追平了,但代碼量膨脹了四倍,且可讀性大打折扣。
這正是 C++ 的生存空間所在——當你愿意接受這種激進的權衡時:
如果你在搞高頻交易(HFT),那么程序因為極小概率的錯誤數據崩潰了,也許可以接受;但如果為了安全檢查拖慢了每一筆交易的速度,那就是不可接受的。開發者只要最純粹、最快的機器碼,任何額外的安全檢查都被視為累贅;
同樣在游戲開發方面,游戲如果出現了一個渲染錯誤,或者像素偏了一點,甚至偶爾崩潰重啟,玩家也許能忍受。但如果為了代碼安全導致幀率下降、開發效率變慢(因為要寫繁瑣的安全注解),那是開發商無法接受的。
除了這種對性能的極致追求,C++ 另一大支柱是歷史慣性。
以科學計算領域為例,C++ 的地位并不完全因為它語言設計得多好,而是因為那里已經沉淀了海量的成熟代碼。這就像 Fortran 一樣——至今像 LAPACK 這樣的 Fortran 庫仍是數值計算的基石。它們經過了數十年的優化,極其穩定高效,沒有任何商業理由去重寫它們。
C++ 也是如此。只要這些龐大的遺留代碼庫(Legacy Codebase)還在運行,只要沒人愿意支付天文數字般的重寫成本,C++ 就將繼續作為這些領域的中流砥柱存在下去。
吳詠煒:這引出了一個關于開發生產力(Productivity)的有趣悖論。剛才你提到,為了在 Rust 中追求極致性能(對齊 C++ 的匯編級優化),代碼量可能會膨脹四倍,這意味著生產力大幅下降。但另一方面,業界許多報告又聲稱 Rust 程序員的生產力顯著高于 C++。
這兩個截然相反的結論同時存在,是否存在矛盾?也許,這是因為它們應用于不同的領域(domain)?
David Sankel:這絕對是領域決定的,不存在矛盾。關鍵在于你是否在順應語言的設計哲學。
如果你試圖逆著 Rust 的性子來——比如非要像寫 C++ 那樣去寫充斥著裸指針和極致微操的“不安全代碼”——那么是的,你會痛苦萬分,生產力會暴跌。
但如果你順勢而為,利用 Rust 擅長的領域——比如進行高層邏輯組裝、編寫默認安全的業務代碼,或者通過安全的接口調用底層高性能庫——你會感受到前所未有的生產力飛躍。
讓我舉一個讓我深受震撼的親身經歷:
有一次我在寫 Rust 項目,突然覺得如果能嵌入一個 JavaScript 解釋器會很棒。在 Rust 里我是怎么做的?我只需要在 Cargo.toml 配置文件里加了一行代碼,引入一個現成的 Crate(庫)。幾秒鐘后,我就擁有了一個功能完備的 JS 解釋器。
試想一下,如果在 C++ 里做同樣的事,會是怎樣的噩夢?
我要找一個合適的 C++ JS 引擎庫。
我要搞定它復雜的依賴項。
我要想辦法讓它的構建系統兼容我自己的構建系統。
我還要處理鏈接、頭文件路徑等一堆瑣事。
在 C++ 里,這是一個天文數字級的工作量;而在 Rust 里,只是“加一行配置”的事。
所以,Rust 所謂的生產力優勢,很大程度上并不在于語言語法本身,而在于其現代化的包管理生態系統。Cargo 對于 C++ 開發者來說,簡直是降維打擊般的體驗提升。
吳詠煒:確實,C++ 的痛點不僅僅在于沒有統一的包管理器,更深層的原因在于底層的二進制不兼容性。我們有 GCC、Clang、MSVC 等不同的編譯器,它們各自有一套不兼容的名稱修飾(Name Mangling)規則和調用約定(Calling Conventions)。這導致在 C++ 中分發預編譯庫(Pre-built Binaries)幾乎是不可能的任務,每個人都必須從源碼重新編譯。
David Sankel:沒錯,編譯器生態的碎片化是一個巨大的阻礙。在 C++ 中,哪怕僅僅是“打包一個庫”這樣看似簡單的動作,都充滿了技術挑戰。
這里有一個非常深刻的對比。Rust(以及幾乎所有現代語言)從誕生之初就吸取了一個教訓:工具鏈必須是語言設計的一等公民。
C++ 只有語言本身(語法和標準庫)被 ISO 標準化了。至于如何構建、如何管理依賴、如何生成文檔……所有這些工具鏈層面的東西,標準委員會采取了“放任自流”的態度。
這種差異導致了結果的天壤之別。以文檔為例:
在 Rust 生態中,官方直接提供了 rustdoc。因此,整個社區只有一種文檔標準,每個人都用同樣的方式編寫注釋,每個人都用同樣的工具生成頁面。這種同質化(Homogeneity)帶來了極大的便利——對于任何一個第三方庫,我閉著眼睛都知道去哪里找文檔,也知道文檔結構長什么樣。而在 C++ 中,這完全是混亂的。
吳詠煒:但我并不認為在 C++ 現有的體系下這具有可行性。坦白說,我甚至反感由 ISO 這樣的機構去強行標準化工具鏈或文檔工具。在我看來,這根本就是不可能完成的任務。
David Sankel:問題的關鍵其實不在于組織是否“正式”,而在于產出物的性質。ISO 標準化流程的核心職能非常單一:發布規格說明書(Specification)。僅此而已。
反觀 Rust 的組織方式,它完全是另一種范式。Rust 不僅僅發布類似規格的 Rust Reference,它更核心的產出是軟件成品。所有這些軟件與文檔的集合體,才構成了我們認知中的“Rust”。它不僅僅是一紙標準,而是一個完整的產品交付。
這就是兩者最根本的區別。ISO 的設立初衷就不是為了開發和維護軟件產品。如果我們試圖強行通過 ISO 流程來構建一套統一的 C++ 工具鏈,結果注定會是一場災難。這不僅違背了 ISO 的基因,在實際操作層面上也完全不可行。
吳詠煒:另一件事是,C++ 的模板特化(Template Specialization),它讓 C++ 在某種程度上完美契合了“開閉原則”(Open-Closed Principle):你可以在完全不修改現有通用模板代碼的前提下,為特定類型提供擴展實現。
然而,Rust 似乎并沒有這種全功能的特化機制,卻依然發展得很好。這是否意味著,特化這個優勢其實并沒有顯現出來?還是說 Rust 有其他的替代方案?
David Sankel:這一點非常有意思。當 Sean Parent 和我的團隊開始集體學習 Rust 時,他直接切入了最硬核的元編程部分。
幾乎是立刻,他就指出了這個痛點:“Rust 沒有特化。如果沒有特化,你就無法進行真正的泛型編程。” 這對習慣了 C++ 強大元編程能力的專家來說,確實是一個巨大的沖擊。
吳詠煒:這就是我不喜歡 Rust 的地方。所以我想聽聽你的看法。也許那真的沒那么重要?或者怎么說?
David Sankel:我必須承認,與 C++ 相比,這確實是 Rust 的一個顯著短板。不僅沒有特化,Rust 目前也缺乏可變參數模板。這就導致你經常需要用笨辦法繞路——比如為了支持不同數量的參數,你得手動把一個函數復制粘貼寫很多個版本。
這種感覺讓我恍惚間回到了原始的 C++98 時代。但這并非設計者的疏忽,而是深層機制權衡的結果。Rust 引入了嚴格的借用檢查器,并且采用了受檢泛型(Checked Generics)模型。
在 C++ 中,即便你定義了 Concept,如果你在模板函數里偷偷用了一個 Concept 沒聲明的操作,只要實例化時的具體類型支持這個操作,C++ 編譯器通常也就睜一只眼閉一只眼放行了。
在 Rust 中(受檢泛型),編譯器極其嚴格。它強制要求泛型函數內部只能使用 Trait(對應 C++ 的 Concept)中顯式聲明的接口。這雖然帶來了極佳的接口契約保證,但也使得實現“特化”和“可變參數”在理論上變得異常困難。
目前,Rust 社區雖然有一些關于如何實現這些特性的構想,但尚未落地,這仍是一個未解的難題。
所以歸根結底,這就是一種取舍問題,你想要受檢泛型帶來的類型安全和清晰契約,就不得不暫時忍受特化能力的缺失。你得自己權衡這種交換是否劃算。
吳詠煒:那么在你和 Sean 的討論中,結論是什么?這個特性對 Adobe 或你的項目真的很重要嗎?從理論角度來看,要想在一種語言中完全實現 Stepanov風格的泛型編程,你真的需要那種特化。我實際上只是希望我的代碼在不修改現有代碼的情況下可擴展。所以我想要符合開閉原則。
David Sankel:我認為你在 Rust 里也能得到開閉原則。你可以先定義一個 Trait,聲明需要哪些函數, 然后再為 Trait 提供一個通用的默認實現。當一個新類型想要使用這個功能時,它必須顯式地為自己實現這個 Trait。
在 C++ 中,泛型函數(如 std::sort)是“即插 即用”的:只要你的類型滿足 Concept(或隱式接口)的要求,編譯器就會自動選用通用實現。而如果你需要更優的路徑,還可以通過模板特化提供定制版本——整個過程無需修改原始泛型代碼,也無需顯式注冊。
但在 Rust 中,這兩種能力無法共存。你要么顯示地選擇加入,然后隨心所欲的進行特化,要不你有一個自動實現,但不能特化它。
吳詠煒:好的,所以我們有辦法,但是是一種非常不同的方式。
David Sankel:是的,完全正確。C++ 中的 Concept,如果你的語法恰好符合 Concept 的要求,你就支持該 Concept。在 Rust 中,你必須顯式地說你支持一個 Trait(這相當于 Concept),并說:“好的,這個特定的類型或這組類型支持這個 Trait,這是它所需的函數的實現。” 所以它是選擇加入(opt-in)的語法。
吳詠煒:好的,下一個問題是關于 AI 代碼的。隨著 AI 編碼助手的興起,許多開源社區正在禁止 AI 生成的貢獻。作為標準委員會的一員,你對此有何看法?委員會有沒有收到或接受過由 AI 生成的提案或措辭?你有親自在 C++ 開發中用過過 AI 工具嗎?如果有,體驗如何?
David Sankel:關于 C++ 標準,確實有過由 AI 編寫的提案,而且非常明顯,也非常令人討厭。那樣寫的提案沒有任何進展。當然,這些是我們知道的。也許有人用 AI 寫了一個,而且寫得太好了以至于我們沒有注意到。但我還沒有真正看到過這種情況。
我認為開源社區保護自己免受 AI 生成代碼貢獻的影響是有道理的。因為 AI 寫出的一段代碼只是完成了一半。另一半是逐行仔細審查,確保它實際上是正確的,并能完成所有需要做的事情。
所以當你有一個開源項目,現在任何人都可以生成做某事的 Pull Request,這意味著該庫的維護者必須投入大量的精力,來應對這些貢獻者投入的零精力。這里需要某種制衡。也許有人必須證明他們值得信任,并確認一個真正的人類已經花時間檢查了這個東西。
我確實有用過 AI 生成代碼。以我的經驗而言,AI 產生的錯誤足以讓我無法信任它生成的任何東西,除非我親自檢查。 任何將要發布或長期使用的東西,我都必須非常非常小心。
它基本上將我寫代碼的精力從“編寫代碼并迭代”轉變為“AI 生成代碼,我仔細審查”。這感覺不太好。你知道,相比于審查代碼,我更喜歡寫代碼,尤其是當我審查 AI 的代碼而它在胡編亂造時,有時候真的很讓我惱火。但總的來說,我認為它在大多數情況下節省了時間。所以這可能是值得的。
AI 會變得更好嗎?有些人認為它將成為最神奇的東西,你再也不用看代碼了。我不相信。我認為對于目前我看到的任何技術和進步,人類都必須保持在循環中(Stay in the loop)。
吳詠煒: 具體來說,你在 C++ 和 Rust 代碼上使用 AI 工具的體驗如何?
David Sankel:對于 C++:AI 傾向于生成更不安全的代碼。
學術研究數據表明,AI 生成的 C++ 代碼在客觀上比人類編寫的代碼更差,尤其是在內存安全漏洞方面。
更令人擔憂的是一種心理學現象:開發者往往對 AI 生成代碼的正確性過度自信,其信心程度甚至超過對自己親手編寫代碼的信心。然而現實恰恰相反——AI 生成的代碼往往包含更多安全隱患。這是一個相當令人不安的趨勢。
對于 Rust,當涉及到內存安全和 AI 生成的代碼時,如果 AI 生成的代碼不安全,它就不會通過編譯。
吳詠煒:對,它是強制性的。這就是區別。
David Sankel:目前 Rust 的語法和特性集比 C++ 小得多、也簡單得多,這使得 AI 更容易生成語法正確、看似合理的代碼。當然,這不意味著絕對可靠——我確實也見過 Rust AI 產生一些非常瘋狂的“幻覺”。
總的來說,我認為無論是 C++ 還是 Rust,現有的代碼語料庫都已足夠龐大,AI 能夠進行有效的學習和代碼生成。
吳詠煒:我認為至少作為一個輔助工具,AI 是非常有幫助的。順便說一句,幾天前我想讓 AI 重構我的一些 C 代碼(其實不是 C++),它識別出了一個潛伏了 10 多年的 Bug,因為它從未被觸發過。但 AI 注意到我在那里有個拼寫錯誤,把一個變量誤寫成了另一個。它識別出來了。所以這非常有趣。
David Sankel:是的,我也遇到過這樣的時刻,它做了一些事情,你會想,“什么?它怎么……?太神了。”
吳詠煒:最后一個問題。我想談談未定義行為(UB)。UB 是大多數內存安全問題的根本原因。目前的標準流程中是否有積極的提案專門旨在減輕未定義行為或增強檢測?例如,通過更好的 Sanitizer 或編譯器診斷?
David Sankel:是的,一直有穩定的提案流試圖解決未定義行為。我相信在 C++26 中,我們首次引入了“錯誤行為”(Erroneous Behavior)這個概念。這使得一些以前未定義的事情現在有了完整的定義。
還有 Profiles(配置)也被提出過,但這類提案目前還非常不成熟,更像是一些初步構想,缺乏任何實現經驗。正因如此,它未能進入 C++26。
讓我有點擔心的是……最近很多關于未定義行為和解決內存安全漏洞的提案確實是一些“異想天開”的主意。你可以舉幾個例子說“這是可以被檢測到的”,但它們缺乏任何算法,更不用說規范或實現了。我擔心這會分散我們的注意力。人們可能會說,“哦,這個問題在未來某個時候會得到解決”,但實際上……那里并沒有實質性的東西。
對我來說,目前最扎實、最有趣的努力,來自于 Timur Doumler 等人的一篇論文。他們沒有急于提出解決方案,而是做了一項極其重要的基礎工作:系統性地編目(Catalog)C++ 標準中每一個已知的 UB 實例,并對它們進行分類。
他們本質上是在用一種科學的方法,為每一個 UB 打上標簽,然后問:“對于這一類 UB,我們到底能做些什么?”雖然他們目前還只是在編目階段,沒有提出具體的解決方案,但我認為這才是正確的方向。它讓我們第一次有可能從宏觀上、系統性地去討論如何逐步消除 UB,而不是頭痛醫頭、腳痛醫腳。
吳詠煒:是的。我想在過去人們認為未定義行為對優化是一件好事。但現在,我認為我們正在朝相反的方向發展。越來越多的人認為未定義行為簡直是邪惡的。我們想盡可能地消除它們,對吧?
David Sankel:完全正確。促成這一觀念轉變的關鍵因素之一,是 CPU 架構的演進。
讓我們以向量(Vector)的索引訪問為例。如果你在訪問時強制加上邊界檢。在過去,這可能會帶來巨大的性能懲罰,甚至讓執行時間變成原來的四倍。而現在,得益于現代超標量架構,配合指令預取和預執行技術,CPU 的流水線能力極強。
這意味著,很多以前昂貴的檢查操作,現在被現代硬件的并行能力“消化”了。實際上,你現在基本上可以“免費”(Free)獲得這些安全檢查,而無需付出明顯的性能代價。
吳詠煒:是很多,但不是全部。因為我確實遇到過一個使用 gsl::span 測試的案例。在這個案例中,使用 gsl::span 配合 std::copy 會使復制代碼慢 20 倍以上。所以如果我們只做一次性檢查,那是可以的。但如果我們不小心做了重復檢查,那代價會非常高昂 。
David Sankel:是的。這也是 Rust 生態系統中存在的問題,因為他們想要非常高效的代碼,但也想要安全。
如果你深入查看 Rust 標準庫的實現,你會發現一種非常巧妙的模式:雖然代碼本質上是“安全”的(意味著理論上每次訪問都要檢查),但開發者會在循環開始前加入一條特定的前置斷言,比如“先檢查并確認長度小于某個值”。
為什么要這么做?因為編譯器(優化器)看到這條前置檢查后,就能推斷出后續操作是安全的,從而在函數主體的循環中自動消除(Elide)所有那些多余的重復檢查。
這就像是開發者與優化器之間的一場“雙人舞”:你通過特定的代碼寫法去“引導”優化器,從而在不犧牲任何安全性的前提下,獲得極高的性能。
我認為在 C++ 領域,我們對這種優化技巧討論得還遠遠不夠,因為我們在內存安全這條路上才剛剛起步。但我相信,同樣的原理和機制在 C++ 中也是完全適用的。
吳詠煒:我認為在這種情況下,有一個參考實現真的很有幫助,因為委員會知道他們可以讓編譯器基于靜態分析進行這樣的優化,對吧?
David Sankel:對。是的。
吳詠煒: 好的。非常感謝您接受今天的采訪。
David Sankel:謝謝。
《近匠》是 CSDN 推出的訪談欄目,其意思即為「走近工匠」,走近深耕于開源、云、AIoT、根技術、數字化轉型、前沿技術的工具創造者和技術管理者們,了解他們怎么看待現在的開發工作,分享自己精雕細琢出來的工具有何特點,剖析整個行業發展現狀及未來趨勢。
為此,基于 AI、開源、系統軟件、數字化轉型、前沿技術等領域,如果您及團隊有報道需求,亦或者如果您有對技術趨勢的真知灼見,或是深度的應用實踐、場景方案等的新見解,歡迎聯系 CSDN 投稿,聯系方式:微信(hanbb120,請備注投稿+姓名+公司職位)、郵箱(tumin@csdn.net)。
未來沒有前后端,只有 AI Agent 工程師。
這場十倍速的變革已至,你的下一步在哪?
4 月 17-18 日,由 CSDN 與奇點智能研究院聯合主辦「2026 奇點智能技術大會」將在上海隆重召開,大會聚焦 Agent 系統、世界模型、AI 原生研發等 12 大前沿專題,為你繪制通往未來的認知地圖。
成為時代的見證者,更要成為時代的先行者。
奇點智能技術大會上海站,我們不見不散!
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
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.