整理丨諾亞
出品 | 51CTO技術棧(微信號:blog51cto)
在不久前TIOBE發布的10月編程語言排行榜上,C++一舉越過Java,摘得探花位,僅次于Python和C。年過四旬的C++依然是全球最流行的編程語言之一,不過近年來一些巨頭的動向也讓C++的安全性頻頻走向爭議的中心。
前有微軟透露正基于Rust 語言改寫 Windows 11 內核,部分替代之前的 C++,后有谷歌聲稱正在將 Android 原生代碼從 C++ 遷移到 Rust,從而進一步減少安全漏洞。
就在外界紛紛揣測C++如何應對突如其來的中年危機,是否真的應該讓位于后起之秀時,近日C++之父Bjarne Stroustrup在上個月舉辦的編程語言年度大會上公開表態:他將增加新的安全工具應對批評,為全球數十億行C++代碼帶來新的解決方案。
圖片
1、反駁:切換到新語言,沒那么簡單
對于那些認為問題出在C++本身、解決方案是改用另一種語言的批評人士,這位已經72歲的大佬予以了駁斥。
第一,安全性指的不僅僅是內存安全。
第二,語言之間的互操作性需求往往會被忽視。
第三,語言切換的成本通常會被低估。
Stroustrup首先指出“通常提到的安全性只是內存安全——這是不夠的......與其他語言(包括C++和C)進行互操作的需求往往不會被提及。而且轉換的成本可能非常高。這一點很少被提及......”
“從我所看到的觀點來看,我們將用大約7種不同的語言來取代C++。也許在距今四十年后,我們可能會有20種不同的語言,它們必須相互操作。這將會很困難。”
Stroustrup還指出,“許多所謂的‘安全’語言將所有底層的東西都外包給了C或C++”,暫時脫離原始語言來訪問硬件資源,甚至操作系統(通常是用C編寫的)——甚至可能是極為古老的、藏在外部庫中的“可信代碼”……
Stroustrup把我們目前的情況稱為“一種漸進式和進化式的方法,而不是一味追求全新的方法。”就像蓋爾定律:“一個有效的復雜系統勢必是從一個有效的簡單系統發展而來的。”
歸根結底,就像Stroustrup所指出的,切換語言可能看起來是在構建一個新系統,但是想越過所有舊系統的問題來解決一切,只是一個幻想。切換語言所要付出的代價可能遠比你理想中的要高。
2、出新:“小心”是行不通的,“我們需要強制執行的規則”
Stroustrup提到了安全性的許多概念,重點介紹了資源泄漏、溢出、內存損壞、計時錯誤、并發錯誤、終止錯誤——當然還有類型錯誤。隨后,他就C++安全性的發展趨向進行了詳細闡釋。
Stroustrup稱當前是“一個機會”,他強調,類型和資源安全從C++誕生之初就一直是它的目標。“我們當時的硬件無法提供完全的安全性,現在也無法對所有語言和所有用例提供完全的安全性。”但是Stroustrup也不希望看到對C++表達的限制,事實上他設想了一個仍然遵循該語言的ISO標準的解決方案。
“我們需要它是C++。也就是說,我們能做什么不應該受到限制,即使我們如何做可能會受到限制。”
與此同時,Stroustrup 也不希望看到大量的額外運行時開銷。“性能不應該有任何下降......實際上,編寫安全代碼的一些技術可以提高性能。我主要談論的是編譯器和靜態檢查可以做什么,因為它是免費的,或者實際上可以提高性能。”
Stroustrup找到了他的解決方案:配置文件。也就是說,一套規則,只要遵守,就能實現特定的安全保證。它們將由ISO C++標準定義,解決常見的安全問題,如指針和數組范圍。
至于添加新工具的困難,Stroustrup指出,C++編譯器本身現在是一個相當復雜的靜態分析器,也可以滿足配置文件的要求。因此,在添加提高安全性的工具時,“我認為配置文件注釋應該有助于解決這個問題”。
Stroustrup列出了一般策略:使用靜態分析來消除潛在的錯誤。但Stroustrup補充說:“全局靜態分析是負擔不起的。”
“所以基本上我們需要規則來簡化我們正在編寫的內容,使其能夠高效、低成本地分析——本地靜態分析……然后提供庫,使依賴這些規則變得可行。”
另外,他還指出了這種策略的另一個優勢:“支持從舊代碼到提供擔保的現代代碼的逐步轉換。”將有一套標準的“基本”擔保,以及更大、更開放的可用擔保。Stroustrup說:“我想象的是類型和資源安全,內存安全,范圍安全。諸如算術安全之類的東西是可以標準化的。”此外,還將制定規則,對不同的代碼片段應用不同的保證。代碼甚至可以得到應用了哪些保證的顯式表達式(從而使將來的讀者放心)。
Stroustrup簡要說明了一點:“小心”是行不通的。因此,雖然核心指導方針可能建議安全的編碼實踐,但“我們需要強制執行的規則”。
“我們必須制定安全使用的規則。我們必須提供方法來驗證人們是否真的在做他們想做的事情。”Stroustrup指出,他所描述的大部分內容已經被嘗試過,甚至有規模化的實踐。“但這些都沒有被整合成一個一致的、連貫的整體。這就是我認為我們應該做的。”
“衛生規則+靜態分析+運行時檢查”就是被提煉出的公式。Stroustrup說C++可以消除許多常見的錯誤,包括未初始化的變量,范圍錯誤,空指針解引用,資源泄漏和懸空引用。
在演講接近尾聲時,Stroustrup談到了更多的細節。“我建議你采用基于模塊的控件。”
export My_module[[provide(memory_safety)]];
import std [[enable(memory_safety)]];
import Mod [suppress(type_safety)]];
還在開發中的是代碼內控件,用于代碼片段。
[[suppress(type_safety)]] X
[[enforce(type_safety)]] X
3、合力:面向開發者的愿望清單
目前這項工作還在進行中,你可以查到與之相關的論文和討論。Stroustrup談到:“從經典的C,從‘帶類的C’,到C++11,我們已經走了很長很長的路。”
面向開發者,Stroustrup建議用戶可以幫助完善配置文件并將其規范形式化。“我夢想著像 Profiles Light 這樣的東西,它提供了配置文件的大部分保證,但不能做所有最后的事情,因為,比如說,靜態分析器還不能做到這一點。”
Stroustrup創建了一個 GitHub 存儲庫,“人們可以在那里提出建議,我將把我的草稿等放在那里,這樣我們就可以創建一個社區,致力于在合理的時間內完成這些事情。
存儲庫詢問需要什么才能使配置文件成為“滿足各種 C++ 安全需求的全行業工具”,并將該概念稱為框架。“為了實現廣泛使用,必須創建和安裝許多部件。雖然我們已經做了很多工作,但廣泛可用的相對較少。這是一個愿望清單。請盡你所能提供幫助。”
圖片
參考鏈接:
https://thenewstack.io/bjarne-stroustrups-plan-for-bringing-safety-to-c/