數(shù)以百計(jì)的 C/C++ 替代品將會(huì)出現(xiàn),但 C/C++ 將永遠(yuǎn)與我們同在!
每個(gè) CPU 都帶有一種稱(chēng)為 ISA(指令集架構(gòu))匯編的電路語(yǔ)言。ISA 程序集是一種硬件語(yǔ)言,由基本數(shù)據(jù)操作、數(shù)學(xué)計(jì)算和結(jié)構(gòu)化編程(即 jmp)的操作組成。但是,為每個(gè)計(jì)算需求編寫(xiě)匯編代碼無(wú)疑是耗時(shí)的,因此過(guò)去的程序員發(fā)明了對(duì)人類(lèi)友好的語(yǔ)言和編譯器。
計(jì)算機(jī)科學(xué)家先驅(qū) Dennis Ritchie 為 Unix 操作系統(tǒng)的研發(fā)需求實(shí)現(xiàn)了 C 語(yǔ)言。在這段時(shí)期,整個(gè)計(jì)算機(jī)技術(shù)領(lǐng)域都在進(jìn)行基礎(chǔ)的最初建設(shè),所以幾乎所有的程序員都使用 C 語(yǔ)言來(lái)構(gòu)建早期的計(jì)算程序,比如編譯器、操作系統(tǒng)、數(shù)據(jù)庫(kù)軟件和網(wǎng)絡(luò)程序。后來(lái),C++ 擴(kuò)展了 C 語(yǔ)言,保留了 C 語(yǔ)言的性能特點(diǎn),一門(mén)具有更多開(kāi)發(fā)人員特性的新的編程語(yǔ)言誕生了。
在 20 世紀(jì) 20 年代,程序員實(shí)現(xiàn)了 C/ C++ 的備選品,如 Go、D、Rust 和 Carbon,它們具有 C/ C++ 從未提供的各種特性。但這些語(yǔ)言仍然只是 C/ C++ 的備選品,而不是替代品,原因如下:
1C 和 C++ 是基礎(chǔ)語(yǔ)言
如果我們追根溯源當(dāng)今活躍在我們生命中的每一款計(jì)算機(jī)程序,總會(huì)發(fā)現(xiàn)它們誕生自 C 或 C++。想想你現(xiàn)在在做什么,你可能在谷歌 Chrome 上讀到這篇文章,Chrome 開(kāi)源瀏覽器 (Blink 渲染引擎、V8 和瀏覽器應(yīng)用程序) 是用 C++ 寫(xiě)的。假如你在 GNU/Linux 上運(yùn)行 Chrome,Linux 內(nèi)核是用 C 寫(xiě)的。MySQL,最流行的關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng),是用 C/ C++ 寫(xiě)的。所有流行的操作系統(tǒng)都為內(nèi)核函數(shù)提供了核心 C 或 C++ API。
即使存在穩(wěn)定的 C/ C++ 替代方案,許多程序員仍然喜歡用 C 或 C++ 進(jìn)行系統(tǒng)編程。在大多數(shù)情況下,程序員選擇 C++ 是因?yàn)樗桥c操作系統(tǒng)級(jí) API 通信的最佳語(yǔ)言。例如,谷歌用 C++ 編寫(xiě)了 Flutter 引擎:
Flutter 引擎使用 C/ C++ 應(yīng)用 GTK 庫(kù)函數(shù),
截圖由作者提供
數(shù)十年來(lái),計(jì)算領(lǐng)域的大多數(shù)核心組件都使用 C/ C++ 作為實(shí)現(xiàn)語(yǔ)言,C/ C++ 語(yǔ)言也長(zhǎng)期維持著語(yǔ)言語(yǔ)法的標(biāo)準(zhǔn)。打造 C/ C++ 的替代品就像在所有的建筑工程完工之后改變房子的地基。
2C 和 C++ 完全控制我們所寫(xiě)的內(nèi)容
在編寫(xiě)源代碼時(shí),C/ C++ 可以自由地處理程序資源。例如,C/ C++ 允許你直接分配 / 釋放用于存儲(chǔ)數(shù)據(jù)元素的物理內(nèi)存。C/ C++ 提供了一種使用本機(jī)操作系統(tǒng)級(jí)線程的方法,而不是像 Go 那樣管理單獨(dú)的并發(fā)運(yùn)行時(shí)。
C/ C++ 沒(méi)有提供自動(dòng)內(nèi)存管理 (垃圾回收) 特性,因此程序員應(yīng)該謹(jǐn)慎有效地防止內(nèi)存泄漏??纯?Meta 的 Folly 庫(kù)源代碼是如何實(shí)現(xiàn)手動(dòng)內(nèi)存管理策略的:
Meta 的 Folly 庫(kù)使用了手動(dòng)內(nèi)存管理功能
自動(dòng)內(nèi)存管理和內(nèi)存處理的限制無(wú)疑是使語(yǔ)言變得現(xiàn)代、高效和更抽象的好方法,但是這些特性會(huì)在語(yǔ)言運(yùn)行時(shí)產(chǎn)生性能開(kāi)銷(xiāo),并降低程序員的自由度。
C 和 C++ 不限制內(nèi)存訪問(wèn),提供手動(dòng)的內(nèi)存管理操作,讓程序員按照自己的意愿控制程序,從而把自由給了程序員。當(dāng)你用 C/ C++ 編寫(xiě)程序時(shí),你的源代碼將有效地執(zhí)行你指示的操作,就是這樣。
3C 和 C++ 確實(shí)又快又高效
一個(gè)特定程序的效率取決于兩個(gè)主要因素:程序員使用的算法的時(shí)間復(fù)雜度和二進(jìn)制程序的效率。毫無(wú)疑問(wèn),我們可以控制算法的復(fù)雜性,因?yàn)槲覀兛梢酝ㄟ^(guò)更新源代碼來(lái)改變它們。另一方面,二進(jìn)制文件是編譯器生成的,因此我們無(wú)法輕易從這方面提高效率。
但是,我們可以選擇一個(gè)能夠生成快速有效的二進(jìn)制文件的編譯器。GNU 編譯器生成特定于平臺(tái)的二進(jìn)制文件,而不嵌入專(zhuān)用的運(yùn)行時(shí)環(huán)境。C 編程執(zhí)行模型使用 crt0 匯編指令段中定義的最小啟動(dòng)代碼。看看下面的例子,Linux 上的 crt0 部分:
在 C 語(yǔ)言中 main 函數(shù)之前執(zhí)行的啟動(dòng)代碼
C++ 無(wú)疑是一門(mén)復(fù)雜的語(yǔ)言,但它不像 Python 和 Golang 那樣提供更高的抽象。此外,它還為你提供了一種使用首選標(biāo)準(zhǔn)語(yǔ)言版本 (即 C++ 14) 進(jìn)行編譯的方法。因此,自現(xiàn)代 C++ 特性使 C++ 開(kāi)發(fā)復(fù)雜化以來(lái),你可以只使用 C++ 中最小的特性。C++ 已經(jīng)有 30 多年的歷史了,并且從早期計(jì)算時(shí)代開(kāi)始就對(duì)其性能進(jìn)行了優(yōu)化。
4C 和 C++ 是學(xué)術(shù)友好型語(yǔ)言
程序員編程通常始于職業(yè)生涯的不同階段。一些程序員在他們上學(xué)的時(shí)候就使用第一臺(tái)計(jì)算機(jī)設(shè)備學(xué)習(xí)編程。然而,大多數(shù)程序員都是在大學(xué)期間提高他們的編程技能的。幸運(yùn)的是,幾乎所有的大學(xué)都是為了讓學(xué)生有機(jī)會(huì)學(xué)習(xí)計(jì)算機(jī)程序如何與硬件組件一起工作而開(kāi)始教授了 C 語(yǔ)言編程。
后來(lái),大多數(shù)大學(xué)教授 C++ 的數(shù)據(jù)結(jié)構(gòu)和算法基礎(chǔ)知識(shí),而不使用 C++ 的復(fù)雜部分。大學(xué)生通常在學(xué)習(xí)了與算法相關(guān)的課程后,就會(huì)進(jìn)入競(jìng)爭(zhēng)激烈的編程領(lǐng)域。大多數(shù)有競(jìng)爭(zhēng)力的程序員都喜歡 C++,因?yàn)樗俣瓤?,?nèi)置的最優(yōu)數(shù)據(jù)結(jié)構(gòu)可用性高,語(yǔ)法少。
Rust 無(wú)疑是一種很好的語(yǔ)言,具有內(nèi)存安全、高性能和內(nèi)置特性,但是 Rust 語(yǔ)法對(duì)于第一次編寫(xiě)代碼的開(kāi)發(fā)人員并不友好。對(duì)于工業(yè)用途來(lái)說(shuō),如果你的團(tuán)隊(duì)希望獲得類(lèi)似 C 語(yǔ)言的最小的高效代碼和類(lèi)似 python 的開(kāi)發(fā)環(huán)境,Go 是一種很好的語(yǔ)言。但是,對(duì)于學(xué)術(shù)用途來(lái)說(shuō),Go 的抽象太過(guò)簡(jiǎn)單,并且不能與傳統(tǒng)的偽代碼保持一致,所以學(xué)術(shù)講師永遠(yuǎn)不會(huì)用 Go 來(lái)替代 C/ C++。
5現(xiàn)代替代方案仍然需要 C,它們專(zhuān)注于不同的目標(biāo)
如前所述,所有 POSIX 操作系統(tǒng)和非 POSIX 操作系統(tǒng) (即 Windows) 都提供了一個(gè) C 庫(kù)來(lái)處理內(nèi)核操作,因此從 C/ C++ 調(diào)用內(nèi)核特性很容易,因?yàn)槲覀儾恍枰帉?xiě)特定于語(yǔ)言的綁定或第三方包裝器。一些操作系統(tǒng)甚至預(yù)先包含 GNU C/ C++ 編譯器和調(diào)試器來(lái)促進(jìn) C/ C++ 的開(kāi)發(fā)。如果我們使用 Rust 和 Go,需要特定于語(yǔ)言的第三方綁定來(lái)與操作系統(tǒng) API 通信?,F(xiàn)代替代語(yǔ)言仍然提供了調(diào)用 C 代碼的方法。例如,Go 提供 Cgo 特性來(lái)調(diào)用 C 代碼。
幾乎所有的 C/ C++ 替代方案都力求用與 C++ 截然不同的語(yǔ)言語(yǔ)法來(lái)提供缺少的 C++ 特性。
如果程序員在尋找 C/ C++ 的替代方案,他們通常會(huì)期望一個(gè)平穩(wěn)且耗時(shí)較少的遷移過(guò)程。
此外,他們也不期望學(xué)習(xí)一門(mén)新語(yǔ)言來(lái)為他們不喜歡的 C/ C++ 特性找到解決方案。
程序員們針對(duì)低層次編程用例設(shè)計(jì)和改進(jìn)了 C 語(yǔ)言,沒(méi)有一種現(xiàn)代語(yǔ)言是完全針對(duì) C 語(yǔ)言的目標(biāo)而創(chuàng)建的。C++ 使 C 語(yǔ)言更具有未來(lái)感,并自低級(jí)編程階段進(jìn)行了提升。Rust、Go、D 和 Carbon 都是 C/ C++ 的備選品——而不是替代品,這些備選品都有自己的未來(lái)目標(biāo)。
6結(jié)語(yǔ)
以前的程序員在 C/ C++ 進(jìn)化時(shí)期書(shū)寫(xiě)了我們的計(jì)算機(jī)歷史。他們用 C 和 C++ 構(gòu)建操作系統(tǒng)內(nèi)核、編程語(yǔ)言、數(shù)據(jù)庫(kù)系統(tǒng)、移動(dòng)操作系統(tǒng)和網(wǎng)絡(luò)軟件。多虧了 C/ C++,現(xiàn)在幾乎所有的現(xiàn)代 Web 服務(wù)都能工作。例如,最流行的 Web 服務(wù)器軟件,如 Apache HTTP 和 Nginx,就是使用 C/ C++ 作為實(shí)現(xiàn)語(yǔ)言。
以前的程序員幾乎用 C/ C++ 編寫(xiě)了所有流行的內(nèi)部網(wǎng)絡(luò)瀏覽器和網(wǎng)絡(luò)軟件組件。Web 開(kāi)發(fā)人員喜歡選擇 Java 和 Node.js 用于 Web 服務(wù),但 Java 和 Node.js 都是因 C/ C++ 而來(lái)的。
一些程序員認(rèn)為像 Rust、Go、D 和 Carbon 這樣的流行語(yǔ)言可以替代 C/ C++。同時(shí),一些程序員考慮使用這些語(yǔ)言作為 C/ C++ 的備選品,認(rèn)為它們?cè)谖磥?lái)可能取代 C/ C++。這些現(xiàn)代語(yǔ)言是為特定的目的和需求而設(shè)計(jì)的——而不是取代 C/ C++。
微軟創(chuàng)建了 TypeScript,但我們?nèi)匀皇褂?JavaScript。Jetbrains 創(chuàng)造了 Kotlin,但我們?nèi)匀皇褂?Java。數(shù)以百計(jì)的 C/ C++ 備選品出現(xiàn)了,但程序員仍將使用 C/ C++,因?yàn)橹貙?xiě)面向 C/ C++ 的計(jì)算機(jī)歷史是不現(xiàn)實(shí)的。
這并不意味著 C 和 C++ 是最好的語(yǔ)言——在某些方面 (例如復(fù)雜性、內(nèi)存安全性等),備選語(yǔ)言可能比 C/ C++ 更好,但它們無(wú)法進(jìn)入 C/ C++ 的領(lǐng)域,因?yàn)橐郧暗某绦騿T用 C 和 C++ 編寫(xiě)了整個(gè)現(xiàn)代計(jì)算機(jī)歷史。
感謝你的閱讀。
審核編輯:湯梓紅
評(píng)論
查看更多