EP 482019-11-071:47:13
C++ 之父的設計哲學與標準化
Bjarne Stroustrup
C++ 設計者回顧語言的設計哲學:零開銷原則、Concepts 為何一路拖到 C++20,以及標準委員會怎麼運作。
Bjarne Stroustrup: C++ | Lex Fridman Podcast #48在 YouTube 看 ↗
重點6 條
- 效能與可靠要同時顧到:Stroustrup 從 Algol 60、Fortran、Pascal 一路試到 Simula,Simula 讓他第一次感受到可以打造自己的型別;C++ 要的是效能與可靠並重,電話要接得通、煞車背後的電腦不能出錯。
- 零開銷原則(zero overhead principle)是設計 C++ 的核心規矩:任何抽象都不能比手寫的低階程式碼慢,他舉矩陣相乘為例,用對的抽象寫出來的程式碼甚至跑得比 Fortran 還快。
- 先簡化,才靠測試把關:他認為降低程式出錯的第一步是簡化——程式碼要能直接表達你想做的事,而不是繞一堆彎才寫出來;大型測試框架也有用,但那是第二步。
- Concepts 從 1987 年左右一直到 C++20 才定案:1987 年左右設計樣板時他就想替參數加上條件限制,但要同時做到夠有彈性、跟手寫一樣快、又能做型別檢查,這三件事一直兜不起來,直到 C++20 才真的能用。
- C++ 標準化是一個開放、靠共識決定的過程:1989 年因為 IBM 與 HP 不想讓公司命脈依賴另一家可能是競爭對手的公司,找上他推動標準化;過去十年一版容易出包,後來改成三年一版。
- 最自豪的還是 C++ 本身:只要他把某件事做對,隔天就有四百五十萬人會用上;C++ 也讓他看到天文台、車廠、JPL 火星車團隊等各種現場,他說如果只是紙上的東西,他撐不了這麼多年。
時間軸26 段
大學時寫的第一支程式用 Algol 60 算超橢圓形狀,那也是他第一個愛上的語言;Fortran、Pascal 沒感覺,組合語言與微碼反而好玩,後來才遇到 Simula。
他心目中程式語言史上最大的突破是 Fortran,讓人能用貼近數學的寫法而不是機器指令;之後 Simula 共同設計者 Kristen Nygaard 來他的學校當客座教授,他在一次次的討論裡學到物件導向。
Lisp 不是他偏愛的語言,他看得出其中的美,但在他那個世界用不上,因為他做的系統常被部署在電話交換機這種沒有工程師在旁邊除錯的環境,負擔不起太有彈性、太動態的語言。
他說「五種」是隨口挑的,重點是別只會一種,第二種最關鍵;現在的清單是機器碼、C++、一種函式語言(ML 或 Haskell)、一種拿來速寫的腳本語言(JavaScript、Python 或 Ruby)。
他提到 CPPCon 一場現場示範:講者把一款乒乓球遊戲的 C++ 程式碼逐步拉高抽象層級,結果編譯出來的組合語言反而更精簡。
他要的是效能與可靠並重的語言:煞車踏板背後的電腦一定要可靠,電話系統的效能不夠就得多堆十倍硬體。
他認為安全、可靠、效能都不是單一模組的事,只顧好自己那一段程式碼、卻不看整個系統,同樣做不出安全的系統。
降低程式出錯的第一步是簡化——先讓程式碼能直接表達你想做的事,而不是繞一堆彎才寫出來;大型測試框架有用,但那是第二步。
他主導整理 C++ core guidelines 限制寫爛程式的可能性,但也直言規則管得到技藝,管不到靈感,好程式跟藝術品一樣需要一點說不清的東西。
靜態分析可以在不執行程式的情況下找漏洞(例如資源沒釋放),但分析不一定完整,也不是每種錯誤都抓得到,還是得配合規則與後續測試。
常被引用的「C++ 是物件導向語言」他說自己沒講過:C++ 支援物件導向,也支援另外九種技巧;設計時也不能想到什麼功能就一個一個往上疊,要有一組規則來決定功能該不該進來。
C++ 的核心規矩是抽象不能比手寫的低階程式碼慢,他舉矩陣相乘為例:用對的抽象反而能跑得比 Fortran 還快。
C++ 從一開始就假設會有很多套實作(不同機器、不同作業系統),他也不喜歡單一實作的壟斷,認為那會讓一方停滯不前、缺乏競爭的誘因。
C++ 有一層貼近硬體、長得很像 C 的低階機制,另一層是讓使用者自己打造型別(class)、用起來跟內建型別一樣好用的抽象機制。
型別之間的共通性可以靠繼承表達(不同車輛都要能「左轉」),也可以靠樣板參數化表達(同一個 vector 可以裝 double、int 或西洋棋棋子)。
編譯器在編譯期把樣板、參數與使用情境三者結合,生成專屬那個型別的程式碼,好處是效能,代價是產生的組合語言很醜,除錯也跟著變得很醜。
Concepts 是替樣板參數加上可以在編譯期檢查的條件(例如「這個型別要能排序」),讓編譯器能先確認參數具備需要的性質。
從 1987 年左右一直到 C++20:1987 年左右設計樣板時他就想同時做到夠彈性、跟手寫一樣快、又能檢查參數型別這三件事,但一直兜不起來,2003 年再試一次也沒成功,直到 C++20 才真正定案。
1989 年 IBM 與 HP 的人找上他,理由是不想讓公司命脈依賴由另一家可能的競爭對手擁有的語言,C++ 因此走上 ISO 開放標準化的路。
第一份 C++ 標準花了八年才完成,原本以為下一版能在六年內做完,結果因為野心變大、想加的東西變多,足足花了十三年才推出 C++11。
為了避免「十年一版、一旦來不及就要再等十一年」的窘境,標準委員會改成三年一次,C++14、17 都準時交付,C++20 也在軌道上。
被問到 C++ 最漂亮的設計,他選建構子與解構子的配對(也就是 RAII):資源在建構子取得、在解構子釋放,這是 C++ 不靠垃圾回收也能可靠管理資源的關鍵。
他認為好的語言設計該來自一組原則,而不是把別人的功能東拼西湊;他提到自己曾跟 Common Lisp 的設計者深聊,發現雙方做法南轅北轍,推理時用的原則卻很相似。
他認為機器學習是完全不同的世界,模糊、靠統計上的準確率運作;但他在意的是飛機、汽車控制這種不能只靠「大多數時候有效」的工程,不希望人人都能寫這類系統。
他對自駕系統感到不安的地方在於:當 AI 系統遇到處理不了的狀況才向人求助,那個人可能正在看書或睡覺,只有三十秒或三秒可以反應,這個交接非常難做好。
回顧一生,他認為最值得驕傲的還是 C++ 本身:只要把某件事做對,隔天就有四百五十萬人會用上;也因此看得到天文台、車廠、JPL 火星車團隊這些現場,如果只是紙上的東西,他撐不了這麼多年。