“AI 寫的C++ 程式碼,客觀上比人類更爛”,吳詠煒對話Adobe 首席科學家David Sankel|近匠

“如果我們必須用對底層的絕對掌控來換取物理極限的性能,那麼C++ 仍然是這個星球上無可替代的語言。”

嘉賓| David Sankel 訪談| 吳詠煒

責編|夢依丹

清單 | CSDN(ID:CSDNnews)

在Rust 強勢崛起、AI 程式重塑開發範式的今天,C++ 這座歷經四十載風雨的程式大廈,似乎正面臨前所未有的生存拷問。

  • 記憶體安全漏洞是否真的無解?

  • AI 產生的程式碼究竟是福音還是隱憂?

  • 當「未定義行為」從優化的基石變為安全的夢魘,C++ 標準委員會將如何應對?

帶著這些尖銳而深刻的問題,在2025 全球C++ 及系統軟體技術大會的採訪間,奇點智能研究院首席技術諮詢師吳詠煒與Adobe 首席科學家、C++ 標準委員會資深委員David Sankel 展開了一場直擊痛點的深度對話。

左:吳詠煒,右: David Sankel

如有興趣觀看完整視頻,可在文末獲取

David Sankel 沒有迴避任何一個敏感話題。從揭示「新程式碼比舊程式碼更脆弱」的反直覺真相,到坦陳C++ 在工具鏈生態上被Rust「降級打擊」的無奈,再到對AI 程式設計助手「既依賴又懷疑」的矛盾心態,Sankel 以一位頂尖語言設計者的視野,為我們抽絲剝繭,還原了一個真實、複雜且充滿生命力的C++ 世界。

這不僅是一場關於科技的探討,更是關於如何在不確定的科技浪潮中尋找確定性的思想碰撞。

以下為對話全文:

吳詠煒:嗨David,歡迎來到全球C++ 及系統軟體技術大會的訪談間。請你先向大家打個招呼。

大衛桑克爾:大家好。真的很高興能來到這裡,感覺特別棒。

吳詠煒:首先,我們來探討一下現代程式碼與遺留系統的安全性問題。你在本次大會演講中提到了一個耐人尋味的趨勢:大多數記憶體安全漏洞源自於新寫的程式碼,而不是遺留系統。 你認為這是什麼原因造成的?是因為語言固有的複雜性、對現代特性的誤用、開發者經驗不足,還是工程流程和工具鏈有缺口?

大衛桑克爾:這個現象的核心在於「代碼硬化」(Code Hardening)的過程,它通常只發生在那些長期承受巨大安全審查壓力的舊程式碼上。

以Zlib 這個古老的C 語言庫為例,多年來,無數人都在積極地試圖攻破它。在這個過程中,絕大多數潛在的漏洞都已經被挖掘並修復了。只要這種對抗性的壓力持續存在,程式碼就會隨著時間的推移而變得越來越堅固。

漏洞出現在新程式碼中的原因,實際上只是因為這些程式碼還沒有時間在那種對抗性壓力下經過「歷練」。這完全是關於漏洞生存週期的問題。如果你看看舊的Zlib 程式碼剛出來的時候,它也有成噸的漏洞,那時候的「遺留程式碼」在當時也是「新程式碼」。這似乎只是公共領域軟體的現象,因為人們總是在試圖攻擊它。

因此,這主要是一個成熟度的問題:程式碼越成熟,Bug 自然越少。

這種現象的正面是,我們不需要回頭去處理所有的程式碼庫。如果你拿Adobe Photoshop 來說,它有6800 萬行程式碼,我們無法回頭去修復所有那些舊程式碼。但好消息是,我們其實不必像防範新程式碼那樣去焦慮舊程式碼。我們將防禦重點集中在新引入的程式碼上,這讓記憶體安全問題從一個「不可能的任務」變成了一個「可控的工程問題」。

吳詠煒:我們知道,在C 語言中,由於開發者通常需要直接管理定長數組和原始內存,所以緩衝區溢位這類問題非常普遍。理論上,C++ 引入了許多現代特性,本應大幅降低此類風險。但現實數據卻表明,我們依然面臨著大量的記憶體相關漏洞。為什麼在機制更完善的C++ 中,這類問題依然無法根除?

大衛桑克爾:C++ 確實透過引入高階抽象化降低了記憶體安全漏洞的發生頻率,但這並不意味著它從根本上消除了隱患。

現實情況是,工程師仍然很容易寫出導致越界存取的程式碼。過去是對C 風格數組的越界,而現在的「現代版本」則是對std::vector 的越界訪問——其本質依然是相同的記憶體安全問題。 再例如使用未初始化的變量,這種風險在C++ 中也並未消失。

歸根結底,C++ 繼承了C 語言的底層記憶體模型和許多「不安全」的基因。只要這些從C 語言遺留下來的底層機制仍然被允許使用,或者現代容器的使用方式缺乏強制性的安全約束,記憶體安全漏洞的溫床就仍然存在。

吳詠煒: 相較於十年前,我們現在擁有了強大得多的動態分析工具。例如Memory Sanitizer (MSan)、Address Sanitizer (ASan)、Thread Sanitizer (TSan) 以及Undefined Behavior Sanitizer (UBSan) 等等

大衛桑克爾:你說得完全正確。問題是:這些工具是否在C++ 生態系中被普遍使用了?遺憾的是,我認為答案是否定的。

阻礙工具普及的原因可分為兩類。一類是主觀因素──例如開發者缺乏認知,或根本不在乎;但更關鍵的,是一類非常現實的客觀門檻:這些工具的配置成本極高。

要讓這套Sanitizer 組合在建造系統中完美運行,需要付出巨大的工程代價。這往往要求你在專案啟動之初就具備極高的前瞻性,並投入資源去配置基礎設施。但在計畫早期,你甚至不知道它能不能存活下去,而且往往無暇顧及這些。

這就導致了一個典型的「成功悖論」:等到你的開源程式庫大獲成功、被廣泛採用時,它可能一直是在沒有Sanitizer 保護的「裸奔」狀態下開發的。突然之間,潛伏的漏洞隨著你的庫擴散到了整個生態鏈。

更糟的是,即便你現在亡羊補牢加上了防護,下游用戶依然可能在使用你的舊版程式碼。為什麼?因為在C++ 生態中,依賴管理和版本升級是一項昂貴的工程活動。使用者往往因為升級成本過高而停留在有漏洞的舊版本上,導致問題持續存在。

吳詠煒:但我認為你的論點可能是我們不想用C++ 寫新程式碼。但其實,我們完全可以在新程式碼中使用這些工具,而不是在舊程式碼中,因為舊程式碼可能有更多的相容性問題。在新程式碼中,我們絕對可以使用新工具。

大衛桑克爾:你的論點建立在一個關鍵假設之上:即只要使用了這些新工具,就能解決所有、或至少絕大部分的記憶體安全漏洞。 誠然,它們能大幅緩解問題,但現實數據卻給我們潑了一盆冷水。

讓我們看看Google 的數據。在Android 系統開發中,他們擁有世界頂級的工程師團隊,並且在C++ 開發流程中強制啟用了所有的Sanitizer 和最佳實踐。即便武裝到了這種程度,他們依然持續發現C++ 程式碼中的記憶體漏洞。

更令人震驚的對比來自於他們引入Rust 之後的資料:在同樣的嚴苛標準下,C++ 程式碼產生的記憶體安全漏洞數量幾乎是Rust 程式碼的1000 倍。

這是一個非常「硬」的數據。它揭示了一個殘酷的現實:工具只能緩解症狀,卻無法根治病灶。

如果單靠打開Sanitizer 就能徹底解決問題,那麼Google 根本不需要大費周章去引入新語言。既然連擁有最強技術實力的Google 都無法在C++ 中徹底封鎖這些漏洞,這本身就證明了這是一個極其艱深、甚至可能是目前範式下無解的難題。

再舉個身邊的例子,我團隊裡的Sean Parent——他是公認的C++ 泰斗級人物——依然會踩進記憶體安全的坑裡。有一次他在處理複雜的模板元編程時,面對層層封裝的抽象,想要搞清楚一個深埋其中的auto&& 到底推導出來的是一個右值引用還是一個指向局部變量的懸垂引用,簡直難如登天。

吳詠煒:是的,我認為抽像是一個大問題,會讓測試constexpr 函數變得很難……我認為模板元程式設計還要更難。實際上,我最近也遇到了一個這樣的問題,也是在元程式設計中。我實際上立即發現了問題,因為程式崩掉了。但要弄清楚問題到底在哪裡真的很難,因為問題隱藏得很深,而且只有在某些特殊場景中才會出現。

大衛桑克爾:對,他的情況也是一模一樣的。

吳詠煒: 好的,讓我們轉向下一個關於C++ 價值主張的問題。如今Rust 憑藉「記憶體安全」特性迅速崛起,Python 在AI 時代更是佔據主導,也確實吸走了一部分原本依賴C++ 的用戶。但在遊戲引擎、系統底層、高效能運算等核心場景,C++ 依舊穩固。在你看來,C++ 最核心、最不可取代的優勢是什麼?為什麼這些優勢至今仍難被其他語言取代?

大衛桑克爾:我認為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)?

大衛桑克爾:這絕對是領域決定的,不存在矛盾。關鍵在於你是否在順應語言的設計哲學。

如果你試圖逆著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)幾乎是不可能的任務,每個人都必須從原始碼重新編譯。

大衛桑克爾:沒錯,編譯器生態的碎片化是一個巨大的阻礙。在C++ 中,即使只是「打包一個函式庫」這樣看似簡單的動作,都充滿了技術挑戰。

這裡有一個非常深刻的對比。 Rust(以及幾乎所有現代語言)從誕生之初就吸取了一個教訓:工具鏈必須是語言設計的一等公民。

C++ 只有語言本身(文法和標準函式庫)被ISO 標準化了。至於如何建構、如何管理依賴、如何產生文件……所有這些工具鏈層面的東西,標準委員會採取了「放任自流」的態度。

這種差異導致了結果的天壤之別。以文檔為例:

在Rust 生態中,官方直接提供了rustdoc。因此,整個社群只有一種文件標準,每個人都用同樣的方式寫註釋,每個人都用同樣的工具產生頁面。這種同質化(Homogeneity)帶來了極大的便利性——對於任何一個第三方庫,我閉著眼睛都知道去哪裡找文檔,也知道文檔結構長什麼樣子。而在C++ 中,這完全是混亂的。

吳詠煒:但我并不认为在 C++ 现有的体系下这具有可行性。坦白说,我甚至反感由 ISO 这样的机构去强行标准化工具链或文档工具。在我看来,这根本就是不可能完成的任务。

大衛桑克爾:問題的關鍵其實不在於組織是否“正式”,而在於產出物的性質。 ISO 標準化流程的核心職能非常單一:發布規格說明書(Specification)。僅此而已。

反觀Rust 的組織方式,它完全是另一種範式。 Rust 不只發布類似規格的Rust Reference,它更核心的產出是軟體成品。所有這些軟體與文件的集合體,才構成了我們認知中的「Rust」。它不僅僅是一紙標準,而是一個完整的產品交付。

這就是兩者最根本的差別。 ISO 的設立初衷就不是為了開發和維護軟體產品。如果我們試圖強行透過ISO 流程來建構一套統一的C++ 工具鏈,結果注定會是一場災難。這不僅違背了ISO 的基因,在實際操作層面也完全不可行。

吳詠煒:另一件事是,C++ 的模板特化(Template Specialization),它讓C++ 在某種程度上完美契合了「開閉原則」(Open-Closed Principle):你可以在完全不修改現有通用模板程式碼的前提下,為特定類型提供擴展實現。

然而,Rust 似乎並沒有這種全功能的特化機制,卻依然發展得很好。這是否意味著,特化這個優勢其實並沒有顯現出來?還是說Rust 有其他的替代方案?

大衛桑克爾:這一點非常有趣。當Sean Parent 和我的團隊開始集體學習Rust 時,他直接切入了最硬派的元程式部分。

幾乎是立刻,他就指出了這個痛點:「Rust 沒有特化。如果沒有特化,你就無法進行真正的泛型程式設計。」這對習慣了C++ 強大元程式設計能力的專家來說,確實是一個巨大的衝擊。

吳詠煒:這就是我不喜歡Rust 的地方。所以我想聽聽你的看法。也許那真的沒那麼重要?或怎麼說?

大衛桑克爾:我必须承认,与 C++ 相比,这确实是 Rust 的一个显著短板。不仅没有特化,Rust 目前也缺乏可变参数模板。这就导致你经常需要用笨办法绕路——比如为了支持不同数量的参数,你得手动把一个函数复制粘贴写很多个版本。

這種感覺讓我恍惚間回到了原始的C++98 時代。但這並非設計者的疏忽,而是深層機制權衡的結果。 Rust 引進了嚴格的借用檢查器,並且採用了受檢泛型(Checked Generics)模型。

在C++ 中,即便你定義了Concept,如果你在模板函數裡偷偷用了一個Concept 沒聲明的操作,只要實例化時的具體類型支援這個操作,C++ 編譯器通常也就睜一隻眼閉一隻眼放行了。

在Rust 中(受檢泛型),編譯器極為嚴格。它強制要求泛型函數內部只能使用Trait(對應C++ 的Concept)中明確宣告的介面。這雖然帶來了極佳的介面契約保證,但也使得實現「特化」和「可變參數」在理論上變得異常困難。

目前,Rust 社群雖然有一些關於如何實現這些特性的構想,但尚未落地,這仍是一個未解的難題。

所以歸根究底,這就是一種取捨問題,你想要受檢泛型帶來的類型安全和清晰契約,就不得不暫時忍受特化能力的缺失。你得自己權衡這種交換是否划算。

吳詠煒:那麼在你和Sean 的討論中,結論是什麼?這個特性對Adobe 或你的專案真的很重要嗎?從理論角度來看,要想在一種語言中完全實現Stepanov風格的泛型編程,你真的需要那種特化。我實際上只是希望我的程式碼在不修改現有程式碼的情況下可擴展。所以我想要符合開閉原則。

大衛桑克爾:我認為你在Rust 裡也能得到開閉原則。你可以先定義一個Trait,宣告需要哪些函數, 然後再為Trait 提供一個通用的預設實作。當一個新類型想要使用這個功能時,它必須明確地為自己實現這個Trait。

在C++ 中,泛型函式(如std::sort)是「即插即用」的:只要你的型別符合Concept(或隱式介面)的要求,編譯器就會自動選用通用實作。而如果你需要更優的路徑,還可以透過模板特化提供客製化版本——整個過程無需修改原始泛型程式碼,也無需明確註冊。

但在Rust 中,這兩種能力無法共存。你要么顯示地選擇加入,然後隨心所欲的進行特化,要么你有一個自動實現,但不能特化它。

吳詠煒:好的,所以我們有辦法,但是是一種非常不同的方式。

大衛桑克爾:是的,完全正確。 C++ 中的Concept,如果你的文法剛好符合Concept 的要求,你就支援該Concept。在Rust 中,你必須明確地說你支持一個Trait(這相當於Concept),並說:「好的,這個特定的類型或這組類型支持這個Trait,這是它所需的函數的實現。」 所以它是選擇加入(opt-in)的語法。

吳詠煒:好的,下一個問題是關於AI 碼的。隨著AI 編碼助理的興起,許多開源社群正在禁止AI 生成的貢獻。作為標準委員會的一員,你對此有何看法?委員會有沒有收到或接受過由AI 產生的提案或措詞?你有親自在C++ 開發中用過AI 工具嗎?如果有,體驗如何?

大衛桑克爾:關於C++ 標準,確實有由AI 編寫的提案,而且非常明顯,也非常令人討厭。那樣寫的提案沒有任何進展。當然,這些都是我們知道的。也許有人用AI 寫了一個,而且寫得太好了以至於我們沒有註意到。但我還沒有真正看到這種情況。

我認為開源社群保護自己免受AI 生成程式碼貢獻的影響是有道理的。因為AI 寫出的一段程式碼只是完成了一半。另一半是逐行仔細審查,確保它實際上是正確的,並能完成所有需要做的事情。

所以當你有一個開源項目,現在任何人都可以產生做某事的Pull Request,這意味著該庫的維護者必須投入大量的精力,來應對這些貢獻者投入的零精力。這裡需要某種制衡。也許有人必須證明他們值得信任,並確認一個真正的人類已經花時間檢查了這個東西。

我確實有用過AI 產生程式碼。就我的經驗而言,AI 產生的錯誤足以讓我無法信任它產生的任何東西,除非我親自檢查。 任何將要發布或長期使用的東西,我都必須非常非常小心。

它基本上將我寫程式碼的精力從「編寫程式碼並迭代」轉變為「AI 生成程式碼,我仔細審查」。這感覺不太好。你知道,比起審查程式碼,我更喜歡寫程式碼,尤其是當我審查AI 的程式碼而它在胡編亂造時,有時真的很讓我惱火。但總的來說,我認為它在大多數情況下節省了時間。所以這可能是值得的。

AI 會變得更好嗎?有些人認為它將成為最神奇的東西,你再也不用看程式碼了。我不相信。我認為對於目前我看到的任何技術和進步,人類都必須保持在循環中(Stay in the loop)。

吳詠煒: 具體來說,你在C++ 和Rust 程式碼上使用AI 工具的體驗如何?

大衛桑克爾:對於C++:AI 傾向於產生更不安全的程式碼。

學術研究數據表明,AI 產生的C++ 程式碼在客觀上比人類編寫的程式碼更差,尤其是在記憶體安全漏洞方面。

更令人擔憂的是一種心理學現象:開發者往往對AI 生成程式碼的正確性過度自信,其信心程度甚至超過對自己親手寫程式碼的信心。然而現實恰恰相反——AI 生成的程式碼往往包含更多安全隱患。這是一個相當令人不安的趨勢。

對於Rust,當涉及到記憶體安全和AI 產生的程式碼時,如果AI 產生的程式碼不安全,它就不會通過編譯。

吳詠煒:對,它是強制性的。這就是差別。

大衛桑克爾:目前Rust 的語法和特性集比C++ 小得多、也簡單得多,這使得AI 更容易產生語法正確、看似合理的程式碼。當然,這不意味著絕對可靠——我確實也見過Rust AI 產生一些非常瘋狂的「幻覺」。

總的來說,我認為無論是C++ 或Rust,現有的程式碼語料庫都已經足夠龐大,AI 能夠進行有效的學習和程式碼產生。

吳詠煒:我認為至少作為一個輔助工具,AI 是非常有幫助的。順便說一句,幾天前我想讓AI 重構我的一些C 程式碼(其實不是C++),它辨識出了一個潛伏了10 多年的Bug,因為它從未被觸發過。但AI 注意到我在那裡有個拼字錯誤,把一個變數誤寫成了另一個。它識別出來了。所以這非常有趣。

大衛桑克爾:是的,我也遇到過這樣的時刻,它做了一些事情,你會想,“什麼?它怎麼…?太神了。”

吳詠煒:最後一個問題。我想談談未定義行為(UB)。 UB 是大多數記憶體安全問題的根本原因。目前的標準流程中是否有積極的提案專門旨在減輕未定義行為或增強檢測?例如,透過更好的Sanitizer 或編譯器診斷?

大衛桑克爾:是的,一直有穩定的提案流試圖解決未定義行為。我相信在C++26 中,我們首次引入了「錯誤行為」(Erroneous Behavior)這個概念。這使得一些以前未定義的事情現在有了完整的定義。

還有Profiles(配置)也被提出過,但這類提案目前還非常不成熟,更像是一些初步構想,缺乏任何實現經驗。正因如此,它未能進入C++26。

讓我有點擔心的是…最近很多關於未定義行為和解決記憶體安全漏洞的提案確實是一些「異想天開」的主意。你可以舉幾個例子說“這是可以被檢測到的”,但它們缺乏任何演算法,更不用說規範或實現了。我擔心這會分散我們的注意力。人們可能會說,“哦,這個問題在未來某個時候會得到解決”,但實際上……那裡並沒有實質性的東西。

對我來說,目前最紮實、最有趣的努力,來自於Timur Doumler 等人的一篇論文。他們沒有急於提出解決方案,而是做了一項極其重要的基礎工作:系統性地編目(Catalog)C++ 標準中每一個已知的UB 實例,並對它們進行分類。

他們本質上是在用一種科學的方法,為每一個UB 打上標籤,然後問:「對於這一類UB,我們到底能做些什麼?」雖然他們目前還只是在編目階段,沒有提出具體的解決方案,但我認為這才是正確的方向。它讓我們第一次有可能從宏觀、系統性地去討論如何逐步消除UB,而不是頭痛醫頭、腳痛醫腳。

吳詠煒:是的。我想在過去人們認為未定義行為對最佳化是件好事。但現在,我認為我們正在朝相反的方向發展。越來越多的人認為未定義行為簡直是邪惡的。我們想盡可能地消除它們,對吧?

大衛桑克爾:完全正確。促成這觀念轉變的關鍵因素之一,就是CPU 架構的演進。

讓我們以向量(Vector)的索引存取為例。如果你在訪問時強制加上邊界檢。在過去,這可能會帶來巨大的效能懲罰,甚至讓執行時間變成原來的四倍。而現在,由於現代超標量架構,配合指令預取與預執行技術,CPU 的管線能力極強。

這意味著,許多以前昂貴的檢查操作,現在被現代硬體的並行能力「消化」了。實際上,你現在基本上可以「免費」(Free)獲得這些安全檢查,而無需付出明顯的效能代價。

吳詠煒:是很多,但不是全部。因為我確實遇過一個使用gsl::span 測試的案例。在這個案例中,使用gsl::span 來配合std::copy 會使複製程式碼慢20 倍以上。所以如果我們只做一次性檢查,那是可以的。但如果我們不小心做了重複檢查,那代價會非常高昂。

大衛桑克爾:是的。這也是Rust 生態系統中存在的問題,因為他們想要非常有效率的程式碼,但也想要安全。

如果你深入查看Rust 標準函式庫的實現,你會發現一個非常巧妙的模式:雖然程式碼本質上是「安全」的(意味著理論上每次存取都要檢查),但開發者會在循環開始前加入一條特定的前置斷言,例如「先檢查並確認長度小於某個值」。

為什麼要這麼做?因為編譯器(優化器)看到這條前置檢查後,就能推斷出後續操作是安全的,從而在函數主體的循環中自動消除(Elide)所有那些多餘的重複檢查。

這就像是開發者與優化器之間的「雙人舞」:你透過特定的程式碼寫法去「引導」優化器,從而在不犧牲任何安全性的前提下,獲得極高的效能。

我認為在C++ 領域,我們對這種優化技巧討論得還遠遠不夠,因為我們在記憶體安全這條路上才剛起步。但我相信,同樣的原理和機制在C++ 中也是完全適用的。

吳詠煒:我認為在這種情況下,有一個參考實作真的很有幫助,因為委員會知道他們可以讓編譯器基於靜態分析進行這樣的最佳化,對吧?

大衛桑克爾:對。是的。

吳詠煒: 好的。非常感謝您接受今天的訪問。

David Sankel:謝謝。

《近匠》是CSDN 推出的訪談欄目,其意思即為「走近工匠」,走近深耕於開源、雲、AIoT、根技術、數位化轉型、前沿技術的工具創造者和技術管理者們,了解他們怎麼看待現在的開發工作,分享自己精雕細琢出來的工具有何特點,剖析整個行業發展現狀及未來趨勢。

為此,基於AI、開源、系統軟體、數位轉型、尖端技術等領域,如果您及團隊有報道需求,亦或者如果您有對技術趨勢的真知灼見,或是深度的應用實踐、場景方案等的新見解,歡迎聯絡CSDN 投稿,聯絡方式:微信(hanbb120,請備註投稿+姓名+公司職位)、電子郵件(tumin@csdn.net)

未來沒有前後端,只有AI Agent 工程師。

這場十倍速的變革已至,你的下一步在哪?

4 月17-18 日,由CSDN 與奇點智能研究院共同主辦「2026 奇點智慧技術大會」將在上海隆重召開,大會聚焦Agent 系統、世界模型、AI 原生研發等12 大前沿專題,為你繪製通往未來的認知地圖。

成為時代的見證者,更要成為時代的先行者。

奇點智慧科技大會上海站,我們不見不散!

分享你的喜愛