C語言天生就與開放結緣。C最初是作為UNIX的系統編程語言而流行起來的,而UNIX可以被認為是第一個產生重大影響的“開源”軟件。隨著UNIX的流行,C語言逐漸被人們認識和喜愛。很快的,在各個平台上C語言都成為了流行的甚至是統治性的程序設計語言。
大約到1980年代中期,C已經成為人類歷史上第一種工業級程序設計世界語。很多人都知道,正是C這樣一種世界語的出現,才使開源運動的出現和最初發展成為可能,從這個意義上講,說C語言是開源運動之母並不十分過分。但人們不太能夠認識到的是,事實上C語言統治地位的獲得,卻也是早期開放軟件運動的直接結果。多數人在回顧這段歷史的時候,經常會感染中國文人的不嚴肅的浪漫主義史觀,喜歡把C語言的成功歸結為漢高祖斬白蛇般的天賦神格,描述為遙想公瑾當年,談笑間樯橹灰飛煙滅的輕飄飄。
然而如果我們對歷史作一些細致的調查,我們會發現C語言絕非有什麼天命,而只不過是幸運地扒上了早期開放運動的快車而已。在C語言“小人乍富”的那幾年,也還有其它不少程序設計語言具有高性能、可移植、系統開發能力強的特點,決不是只有C骨骼特異,貌若天仙。如果Pascal也能借助一個像UNIX那樣的開放的幽靈在歐美大學校園裡徘徊,那麼我們今天很可能要把begin和end直接映射到鍵盤上。
如果IBM不是在1970年代極端保守地把一種叫做PL/X的語言牢牢地限定在自己的研究所裡,也許整個程序員社群的圖騰就不是貝爾試驗室的那兩個大胡子,而是小沃森實驗室裡的IBM某院士。事實上,C語言的成功,更須拜開放軟件運動之時勢所賜,或者更確切地說,C與開放軟件是一對共生體,它們相互扶持,相互成就,共同成長興旺,共同創造歷史。
根深自然葉茂。今天C語言體系內所擁有的開放資源,無論是數量和質量,還是豐富性、多樣性、創新性、可靠性、重要性,都是其它任何開發技術體系所無法望其項背的。豐富對於開發者是好事,但對於寫資源介紹性文章的作者來說,則是絕對的壞事。想要對C語言體系中的開放資源做一個介紹,哪怕只是一次白描,也決不是一個人、一本書所能容納的,更遠遠不是雜志中的一篇文章所能及的。因此在本文中,對於C語言開放資源的介紹是以一種蜻蜓點水的姿態進行的。
相比之下,C++語言在開源世界中的分量,與C語言相比就相去甚遠了。作為對照,C++語言在工業界的實際地位,如果不是比C更重要的話,至少也是與C在同一個層次上。考慮到這一點,在開源領域中兩兄弟的這種差距就令人感到非常震驚。如果說在2000年以前,由於C++在工業界的統治地位,這種差距對C++的影響還不大的話,今天,C++在開源領域裡薄弱的基礎就非常要命了。現在在開發者社群中,“C語言萬壽無疆,C++無壽無疆”的說法得到不少人的支持,其根本原因之一就在於C++在開源運動中的地位遠遜於C。究其原因,歸根到底是因為編寫高質量、可復用而又拳拳服膺的C++程序庫實在是一件太困難的事情。一方面,大量的C++開源項目質量不佳,而且經常以一種粗暴的方式要求使用者改變自己程序的風格,另一方面,一旦有人完成了一個可用的C++項目或者程序庫,他必須具有極其彪悍的意志才能夠咬著牙把這樣的項目奉獻給開源社群——不僅因為失去了可能的金錢上的回報,更因為可能要面對著暴風雨般的批評和鄙視。總之,諸多的原因使得開源文化未能在C++中深深扎根。
然而,畢竟C++是一種稱霸一時的語言,C++社群的規模、強悍和創造力,仍然是很多其它新興語言社群難以相比的。特別是在標准C++制定之後,C++編程風格有了明確的指導思路,開源項目也就大大繁榮起來。雖然時間還不長,但是已經有一些令人欣慰的成果。這些成果也就構成了寫作本文的基本動機和素材。
就重要性而言,開源程序庫和工具集對於C++甚至比對C還要重要得多。因為實踐證明,沒有良好的基礎設施支持,C++開發成功的可能性異乎尋常的低。其根本原因是,用C++寫優秀的程序庫非常非常難,而一旦有了這樣的程序庫,在其基礎上寫應用程序就相當容易了。同時,C++的特點又要求基礎設施的源代碼必須開放,因此,C++程序庫對於開發者來說意義非常重大。
我們可以更進一步探究開源C++程序庫對於C++開發的重要意義。用C++編寫可復用程序庫時所需要的思想方法和技術風格,與用C++編寫應用程序時所需要的思想方法和技術風格之間存在相當大的差異和差距。前者所需要的高超技術、豐富經驗和良好的權衡能力,是很少有人能具備的。在所有程序設計語言中,你恐怕找不出第二種語言像C++那樣,對於程序庫作者的要求如此之高,以至於遠遠超過了一般“熟練”C++開發者的平均水平。在Lisp中,語言、庫和程序根本就是一回事,每一個程序員寫的代碼都可以看成是語言本身的擴充。
在Java、C、Perl、Python、Ruby中,一個優秀的應用程序開發者在積累一定經驗之後,不難寫出高質量的可復用代碼。而在C++中,這種事情是非常罕見的,即使是天資卓越、經驗豐富的大師級人物,也需要花費多年的打磨,歷經幾次反復,才能夠最終推出受到一致認可的可復用程序庫。此道之難,難於上青天,以至於Andrei Alexandrescu感歎道,十幾歲的少年天才滿目皆是,滿鬓斑白的優秀程序庫設計者鳳毛麟角。而在另一個地方,一本C++可復用技術圖書的作者總結道,所謂可復用的C++程序庫,不可能是設計出來的,只可能是復用出來的。然而,一旦這樣的程序庫構造出來並且為人們熟悉,那麼就會大大地簡化應用程序的開發。這也就是為什麼在2000年後,Bjarne Stroustrup無數次地呼吁社群專注程序庫的開發。他很清楚,只有程序庫能夠救C++,只有程序庫能夠發展C++。
現在我們知道,用來寫C++程序庫所需要的技術,與用來寫C++應用程序所需要的技術存在很大的差別。這已經比較糟糕了。更糟糕的是,一般的C++開發者根本分不清這中間的差別,他們在開發中往往既不是一個稱職的程序庫開發者,也不是一個單純的應用開發者。他們一邊想著完成手頭的工作,一邊琢磨如何能夠寫出高質量的基礎庫和框架,為萬世開太平。如果說C語言是一把輕快的小匕首,遇誰都是進身猛刺,血濺一尺,那麼這種C++的使用方式無異於左手打鐵鑄兵,右手揮劍刺秦,這種精神分裂的狀態直接將很多項目變成了既超期超支又質量低劣的垃圾。
認識到這樣的事實之後,C++程序員應當以更理性的態度來看待自己的工作。大部分情況下,你所需要做的是尋找一些可以互相合作的、穩定可靠的開源程序庫,然後在其基礎之上,面向目標,使用盡可能簡樸的技術,專心專意地進行應用開發,把那些復雜精妙的語言技巧和“可復用”之類的想法扔到Java國去。唯其如此,你才可能更高效地開發出好的應用軟件,而且會逐漸積累和重構出真正可復用的軟件。