新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > 工程師:我與C語言長別離了,因為...

工程師:我與C語言長別離了,因為...

作者: 時間:2018-04-08 來源:網(wǎng)絡(luò) 收藏

  這幾天來,我在思考那些正在挑戰(zhàn)的系統(tǒng)編程語言領(lǐng)袖地位的新潮語言,尤其是Go和Rust。思考的過程中,我意識到了一個讓我震驚的事實——我有著35年的經(jīng)驗。每周我都要寫很多C代碼,但是我已經(jīng)記不清楚上一次我創(chuàng)建一個新的項目是在什么時候了。

本文引用地址:http://butianyuan.cn/article/201804/377985.htm

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

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

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

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

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

  這個應(yīng)用完全是用來處理文本輸入的,而且只需要能夠應(yīng)對人類的反應(yīng)速度即可(大概0.1秒),因此使用C或者別的沒有動態(tài)內(nèi)存分配以及字符串類型的語言來寫就會顯得很傻。但是在當(dāng)時,我僅僅是把其視為一個試驗,而完全沒有想到我?guī)缀踉僖膊粫谝粋€新項目的第一個文件里敲下intmain(intargc,char**argv)這樣的C語言代碼了。

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

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

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

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

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

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

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

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

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

  在2000年以后,盡管我還在使用C/C++寫之前的項目,比如GPSD,游戲韋諾之戰(zhàn)以及NTPsec,但是我的所有新項目都是使用Python的。

  有很多程序是在完全無法在C語言下寫出來的,尤其是reposurgeon以及doclifter這樣的項目。由于C語言受限的數(shù)據(jù)類型本體論以及其脆弱的底層數(shù)據(jù)管理問題,嘗試用C寫的話可能會很恐怖,并注定失敗。

  甚至是對于更小的項目——那些可以在C中實現(xiàn)的東西——我也使用Python寫,因為我不想花不必要的時間以及精力去處理內(nèi)核轉(zhuǎn)儲問題。這種情況一直持續(xù)到去年年底,持續(xù)到我創(chuàng)建我的第一個Rust項目,以及成功寫出第一個使用Go語言的項目。

  如前文所述,盡管我是在討論我的個人經(jīng)歷,但是我想我的經(jīng)歷體現(xiàn)了時代的趨勢。我期待新潮流的出現(xiàn),而不是僅僅跟隨潮流。在98年的時候,我就是Python的早期使用者。來自TIOBE的數(shù)據(jù)則表明,在Go語言脫胎于公司的實驗項目并剛剛從小眾語言中脫穎而出的幾個月內(nèi),我就開始實現(xiàn)自己的第一個Go語言項目了。

  總而言之:直到現(xiàn)在第一批有可能挑戰(zhàn)C語言的傳統(tǒng)地位的語言才出現(xiàn)。我判斷這個的標(biāo)準很簡單——只要這個語言能讓我等C語言老手接受不再寫C的事實,這個語言才“有可能”挑戰(zhàn)到C語言的地位——來看啊,這有個新編譯器,能把C轉(zhuǎn)換到新語言,現(xiàn)在你可以讓他完成你的全部工作了——這樣C語言的老手就會開心起來。

  Python以及和其類似的語言對此做的并不夠好。使用Python實現(xiàn)NTPsec(以此舉例)可能是個災(zāi)難,最終會由于過高的運行時開銷以及由于垃圾回收機制導(dǎo)致的延遲變化而爛尾。如果需求是針對單個用戶且只需要以人類能接受的速度運行,使用Python當(dāng)然是很好的,但是對于以機器的速度運行的程序來說就不總是如此了——尤其是在很高的多用戶負載之下。這不只是我自己的判斷——因為拿Go語言來說,它的存在主要就是因為當(dāng)時作為Python語言主要支持者的Google在使用Python實現(xiàn)一些工程的時候也遭遇了同樣的效能痛點。

  Go語言就是為了解決Python搞不定的那些大多由C語言來實現(xiàn)的任務(wù)而設(shè)計的。盡管沒有一個全自動語言轉(zhuǎn)換軟件讓我很是不爽,但是使用Go語言來寫系統(tǒng)程序?qū)ξ襾碚f不算麻煩,我發(fā)現(xiàn)我寫Go寫的還挺開心的。我的很多C編碼技能還可以繼續(xù)使用,我還收獲了垃圾回收機制以及并發(fā)編程機制,這何樂而不為?

  (這里有關(guān)于我第一次寫Go的經(jīng)驗的更多信息)

  本來我想把Rust也視為“C語言要過時了”的例證,但是在學(xué)習(xí)并嘗試使用了這門語言編程之后,我覺得這種語言現(xiàn)在還沒有做好準備。也許5年以后,它才會成為C語言的對手。

  隨著2017的尾聲來臨,我們已經(jīng)發(fā)現(xiàn)了一個相對成熟的語言,其和C類似,能夠勝任C語言的大部分工作場景(我在下面會準確描述),在幾年以后,這個語言界的新星可能就會取得成功。

  這件事意義重大。如果你不長遠地回顧歷史,你可能看不出來這件事情的偉大性。三十年了——這幾乎就是我作為一個程序員的全部生涯,我們都沒有等到一個C語言的繼任者,也無法遙望C之后的系統(tǒng)編程會是什么樣子的。而現(xiàn)在,我們面前突然有了后C時代的兩種不同的展望和未來……

  ……另一種展望則是下面這個語言留給我們的。我的一個朋友正在開發(fā)一個他稱之為“Cx”的語言,這個語言在C語言上做了很少的改動,使得其能夠支持類型安全;他的項目的目的就是要創(chuàng)建一個能夠在最少人力參與的情況下把古典C語言修改為新語言的程序。我不會指出這位朋友的名字,免得給他太多壓力,讓他做出太多不切實際的保證。但是他的實現(xiàn)方法真的很是有意思,我會盡量給他募集資金。

  現(xiàn)在,我們看到了可以替代C語言實現(xiàn)系統(tǒng)編程的三種不同的可能的道路。而就在兩年之前,我們的眼前還是一片漆黑。我重復(fù)一遍:這件事情意義重大。

  我是在說C語言將要滅絕嗎?不是這樣的,在可預(yù)見的未來里,C語言還會是操作系統(tǒng)的內(nèi)核編程以及設(shè)備固件編程的主流語言,在這些場景下,盡力壓榨硬件性能的古老規(guī)則還在奏效,盡管它可能不是那么安全。

  現(xiàn)在那些將要被C的繼任者攻破的領(lǐng)域就是我之前提到的我經(jīng)常涉及的領(lǐng)域——比如GPSD以及NTPsec、系統(tǒng)服務(wù)以及那些因為歷史原因而使用C語言寫的進程。還有就是以DNS服務(wù)器以及郵件傳輸代理——那些需要以機器速度而不是人類的速度運行的系統(tǒng)程序。

  現(xiàn)在我們可以對后C時代的未來窺見一斑,即上述這類領(lǐng)域的代碼都可以使用那些具有強大內(nèi)存安全特性的C語言的替代者實現(xiàn)。Go、Rust或者Cx,無論是哪個,都可能使C的存在被弱化。比如,如果我現(xiàn)在再來重新實現(xiàn)一遍NTP,我可能就會毫不猶豫的使用Go語言去完成。



關(guān)鍵詞: C語言 Python

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉