1. 程式人生 > >與 C 語言長別離

與 C 語言長別離

領域 一次 內存管理 argc posix enter 編譯 bsp 而在

這幾天來,我在思考那些正在挑戰 C 語言的系統編程語言領袖地位的新潮語言,尤其是 Go 和 Rust。思考的過程中,我意識到了一個讓我震驚的事實 —— 我有著 35 年的 C 語言經驗。每周我都要寫很多 C 代碼,但是我已經記不清楚上一次我 創建一個新的 C 語言項目 是在什麽時候了。 技術分享圖片

如果你完全不認為這種情況令人震驚,那你很可能不是一個系統程序員。我知道有很多程序員使用更高級的語言工作。但是我把大部分時間都花在了深入打磨像 NTPsec、 GPSD 以及 giflib 這些東西上。熟練使用 C 語言在這幾十年裏一直就是我的專長。但是,現在我不僅是不再使用 C 語言寫新的項目,甚至我都記不清我是什麽時候開始這樣做的了,而且……回頭想想,我覺得這都不是本世紀發生的事情。

這個對於我來說是件大事,因為如果你問我,我的五個最核心軟件開發技能是什麽,“C 語言專家” 一定是你最有可能聽到的之一。這也激起了我的思考。C 語言的未來會怎樣 ?C 語言是否正像當年的 COBOL 語言一樣,在輝煌之後,走向落幕?

我恰好是在 C 語言迅猛發展,並把匯編語言以及其它許多編譯型語言擠出主流存在的前幾年開始編程的。那場過渡大約是在 1982 到 1985 年之間。在那之前,有很多編譯型語言爭相吸引程序員的註意力,那些語言中還沒有明確的領導者;但是在那之後,小眾的語言就直接毫無聲息的退出了舞臺。主流的語言(FORTRAN、Pascal、COBOL)則要麽只限於老代碼,要麽就是固守單一領域,再就是在 C 語言的邊緣領域頂著愈來愈大的壓力茍延殘喘。

而在那以後,這種情形持續了近 30 年。盡管在應用程序開發上出現了新的動向: Java、 Perl、 Python, 以及許許多多不是很成功的競爭者。起初我很少關註這些語言,這很大一部分是因為在它們的運行時的開銷對於當時的實際硬件來說太大。因此,這就使得 C 的成功無可撼動;為了使用和對接大量已有的 C 語言代碼,你得使用 C 語言寫新代碼(一部分腳本語言嘗試過打破這種壁壘,但是只有 Python 有可能取得成功)。

回想起來,我在 1997 年使用腳本語言寫應用時本應該註意到這些語言的更重要的意義的。當時我寫的是一個名為 SunSITE 的幫助圖書管理員做源碼分發的輔助軟件,當時使用的是 Perl 語言。

這個應用完全是用來處理文本輸入的,而且只需要能夠應對人類的反應速度即可(大概 0.1 秒),因此使用 C 或者別的沒有動態內存分配以及字符串類型的語言來寫就會顯得很傻。但是在當時,我僅僅是把其視為一個試驗,而完全沒有想到我幾乎再也不會在一個新項目的第一個文件裏敲下 int main(int argc, char **argv) 這樣的 C 語言代碼了。

我說“幾乎”,主要是因為 1999 年的 SNG。 我想那是我最後一個用 C 從頭開始寫的項目了。

在那之後我寫的所有的 C 代碼都是在為那些上世紀已經存在的老項目添磚加瓦,或者是在維護諸如 GPSD 以及 NTPsec 一類的項目。

當年我本不應該使用 C 語言寫 SNG 的。因為在那個年代,摩爾定律的快速叠代使得硬件愈加便宜,使得像 Perl 這樣的語言的執行效率也不再是問題。僅僅三年以後,我可能就會毫不猶豫地使用 Python 而不是 C 語言來寫 SNG。

在 1997 年我學習了 Python, 這對我來說是一道分水嶺。這個語言很美妙 —— 就像我早年使用的 Lisp 一樣,而且 Python 還有很酷的庫!甚至還完全遵循了 POSIX!還有一個蠻好用的對象系統!Python 沒有把 C 語言擠出我的工具箱,但是我很快就習慣了在只要能用 Python 時就寫 Python ,而只在必須使用 C 語言時寫 C。

(在此之後,我開始在我的訪談中指出我所謂的 “Perl 的教訓” ,也就是任何一個沒能實現和 C 語言語義等價的遵循 POSIX 的語言都註定要失敗。在計算機科學的發展史上,很多學術語言的骨骸俯拾皆是,原因是這些語言的設計者沒有意識到這個重要的問題。)

顯然,對我來說,Python 的主要優勢之一就是它很簡單,當我寫 Python 時,我不再需要擔心內存管理問題或者會導致核心轉儲的程序崩潰 —— 對於 C 程序員來說,處理這些問題煩的要命。而不那麽明顯的優勢恰好在我更改語言時顯現,我在 90 年代末寫應用程序和非核心系統服務的代碼時,為了平衡成本與風險都會傾向於選擇具有自動內存管理但是開銷更大的語言,以抵消之前提到的 C 語言的缺陷。而在僅僅幾年之前(甚至是 1990 年),那些語言的開銷還是大到無法承受的;那時硬件產業的發展還在早期階段,沒有給摩爾定律足夠的時間來發揮威力。

盡量地在 C 語言和 Python 之間選擇 C —— 只要是能的話我就會從 C 語言轉移到 Python 。這是一種降低工程復雜程度的有效策略。我將這種策略應用在了 GPSD 中,而針對 NTPsec , 我對這個策略的采用則更加系統化。這就是我們能把 NTP 的代碼庫大小削減四分之一的原因。

但是今天我不是來講 Python 的。盡管我覺得它在競爭中脫穎而出,Python 也未必真的是在 2000 年之前徹底結束我在新項目上使用 C 語言的原因,因為在當時任何一個新的學院派的動態語言都可以讓我不再選擇使用 C 語言。也有可能是在某段時間裏在我寫了很多 Java 之後,我才慢慢遠離了 C 語言。

我寫這個回憶錄是因為我覺得我並非特例,在世紀之交,同樣的發展和轉變也改變了不少 C 語言老手的編碼習慣。像我一樣,他們在當時也並沒有意識到這種轉變正在發生。

與 C 語言長別離