C++使用經(jīng)驗(yàn)總結(jié)

寫在前面

借著公司內(nèi)和其他小組的一個(gè)分享科侈,把自己幾年來C++開發(fā)的一點(diǎn)思考總結(jié)一下。全篇沒有高屋建瓴的觀點(diǎn)孝凌,基本都是些細(xì)節(jié)方面的注意事項(xiàng)离钝。希望能給大家提供一點(diǎn)幫助票编。

構(gòu)建工具

C/C++世界里有不少的構(gòu)建工具:make、autotools卵渴、scons慧域、CMake、Bazel浪读。但近幾年比較流行的昔榴,也就是CMake和Bazel。所以這一部分碘橘,也就大概對(duì)比下這兩個(gè)工具吧互订。

究竟該選擇哪個(gè)工具,我覺得可以從如下幾個(gè)方面來對(duì)比一下:

1. 上手難度

因?yàn)锽azel采用了類似Python的語法痘拆,所以其學(xué)習(xí)曲線相比CMake要平緩一些仰禽。但當(dāng)我們考慮上手難度時(shí),除了學(xué)習(xí)曲線之外纺蛆,還要考慮文檔的完備性吐葵、該工具的通用性等各個(gè)角度。當(dāng)綜合考慮時(shí)桥氏,我覺得CMake是一個(gè)盡管保守但仍舊不錯(cuò)的選擇温峭。主要原因就在于,CMake幾乎已經(jīng)成為現(xiàn)在C++的事實(shí)標(biāo)準(zhǔn)字支。使用CMake凤藏,就意味著:

  • 你可以把你熟悉CMake的技能用在折騰別的C++項(xiàng)目上奸忽。而這點(diǎn)之所以重要,是因?yàn)槟阍诶媚硞€(gè)第三方庫的時(shí)候清笨,往往需要大概研究下它的編譯過程月杉。
  • CMake的官方文檔和stackoverflow上的問答也比較完善刃跛。一旦遇到一個(gè)問題抠艾,往往通過搜索引擎能快速的得到答案。

另外桨昙,從設(shè)計(jì)理念上來看检号,CMake提供的解決方案是改革式的:它并沒有提供一個(gè)全新的解決方案,而是和Make蛙酪、Visual Studio或者其他現(xiàn)有的構(gòu)建工具來結(jié)合使用的齐苛。而這就使得你無需丟棄在其他工具上所積累起來的開發(fā)經(jīng)驗(yàn)——例如你熟悉make工具,哪怕是一個(gè)CMake維護(hù)的項(xiàng)目桂塞,你也可以毫不費(fèi)力就知道如何來查看編譯參數(shù)凹蜂,以及控制編譯并發(fā)度等等。

而對(duì)于Bazel則不是如此阁危。Bazel完全以革命者的姿態(tài)完整提供了一整套解決方案玛痊,所有的使用細(xì)節(jié)你都要從頭開始。加上文檔的匱乏狂打,這就使得你也得花上一段時(shí)間擂煞,才能熟悉Bazel。

2. thirdparty的管理

Bazel內(nèi)置了對(duì)thirdparty源碼級(jí)別依賴的支持

  • thirdparty可以是用Bazel構(gòu)建的趴乡,也可以不是对省。對(duì)于非Bazel項(xiàng)目,你需要額外為其添加一個(gè)Bazel的描述文件晾捏。
  • thirdparty可以是一個(gè)本地項(xiàng)目蒿涎,也可以是一個(gè)git倉庫或者h(yuǎn)ttp鏈接

所以總的來看,Bazel對(duì)thirdparty支持還是非常友好的惦辛。

就這點(diǎn)對(duì)比來看劳秋,CMake其實(shí)做的是不太好的。CMake盡管也有ExternalProject的feature裙品,但根據(jù)實(shí)際經(jīng)驗(yàn)來看俗批,使用和維護(hù)都比較的復(fù)雜。所以我還是更傾向于寫幾個(gè)腳本來下載和編譯這些thirdparty依賴市怎。

這里可以拿我參與維護(hù)的Pegasus項(xiàng)目為例岁忘。在該項(xiàng)目中,我們依賴了幾個(gè)不同類型的項(xiàng)目:

  • 從構(gòu)建工具上來看区匠,這些依賴有使用CMake的干像,有使用make的帅腌,有使用autotools的
  • 從來源上來看,有的依賴來自git倉庫麻汰,有的來自http鏈接速客,有的則是從一個(gè)大的項(xiàng)目里面挑選了一個(gè)更小的模塊使用
  • 從代碼的使用方式上來看,有的是直接拿來用五鲫,有的還需要稍微修改下源代碼溺职。

而通過shell腳本,這些各種各樣的場(chǎng)景我們都能非常方便位喂、直接浪耘、易維護(hù)的得以支持。

3. 其它

Bazel和CMake當(dāng)然還有些其它方面值得對(duì)比塑崖,但并非一些通用的點(diǎn)七冲,這里就簡單列舉下,不再詳細(xì)展開了:

  • IDE集成
  • 緩存編譯結(jié)果规婆,從而加速編譯過程
  • 多語言混合變成的支持
  • 分布式編譯
  • 跨平臺(tái)的支持

再補(bǔ)充一個(gè)別人的討論鏈接, 有需求的可以參考一下澜躺。

編程規(guī)范

強(qiáng)烈推薦Google C++ Style。盡管它禁止了很多C++ feature而被很多人黑的很慘抒蚜,但從工程的角度而言掘鄙,它的確提供了非常多極其中肯的建議。說到底削锰,編程規(guī)范的存在通铲,主要就是可以讓水平參差不齊的工程師們,可以在一起協(xié)作出風(fēng)格較為一致的項(xiàng)目來器贩。

也存在一些工具可以對(duì)google規(guī)范進(jìn)行檢查:

因?yàn)間oogle的規(guī)范文檔對(duì)C++ feature的取舍原因講的非常好颅夺,這里就不再贅述了。唯一想補(bǔ)充的是異常

  • C++在語法層面對(duì)異常支持不太友好:你無法通過函數(shù)簽名來得知一個(gè)函數(shù)到底會(huì)拋出哪些異常蛹稍。例如:
    void GetSomeResource(const char* resource_name);
    
    如果這個(gè)接口沒有良好文檔或注釋吧黄,并且也沒有代碼可翻時(shí),你在調(diào)用這個(gè)接口時(shí)很有可能會(huì)漏掉一些錯(cuò)誤情況——因?yàn)樗赡軖伋霎惓K艚恪8氖寝挚粋€(gè)疏于捕獲的異常一旦觸發(fā),線上的程序就會(huì)crash奉芦。
    其實(shí)解釋這么多赵抢,大家只要和Java中的異常機(jī)制對(duì)比一下,就高下立判了声功。對(duì)于這個(gè)話題烦却,王垠的這篇博客值得一看的。
  • 在運(yùn)維Pegasus項(xiàng)目時(shí)先巴,遇到過一個(gè)老版本glibc的bug:如果多個(gè)線程同時(shí)拋出異常其爵,程序會(huì)陷入死循環(huán)冒冬。這個(gè)bug的發(fā)現(xiàn)也是個(gè)有趣的過程,后面我專門寫篇文章展開吧摩渺。
  • 在禁用異常后简烤,程序就只能用錯(cuò)誤碼來進(jìn)行錯(cuò)誤處理。對(duì)于很多項(xiàng)目摇幻,大家都采用一套類似的范式横侦,可以參考tensorflow的做法

C++的新特性

如果能使用C++的新特性,當(dāng)然是盡量使用的好囚企。我自己在開發(fā)中丈咐,覺得非常方便必須使用的新特性有:

  • 智能指針
  • 右值瑞眼,以及C++14中右值得capture
  • lambda, bind
  • initialize list

想補(bǔ)充說一下的是auto龙宏,我自己不是特別喜歡這個(gè)feature,也非常贊同google規(guī)范中的對(duì)auto的限制:僅當(dāng)可以提高代碼可讀性時(shí)伤疙,使用auto

這里不由得就想扯起java 10中的var银酗。雖然能方便開發(fā),但覺得更多的是會(huì)被濫用徒像。而一個(gè)可能被濫用的feature黍特,還不如沒有的好。

第三方utility

在做項(xiàng)目開發(fā)的時(shí)候锯蛀,一般會(huì)有很多瑣碎的需求灭衷,從而也需要很多utility工具包。這里把我遇到的一些需求整理一下:

  • 算法和數(shù)據(jù)結(jié)構(gòu):stl, boost
  • 錯(cuò)誤碼管理:參見tensorflow
  • C語言的字符串封裝:string_view
  • 字符串的各種操作旁涤、轉(zhuǎn)換翔曲、打印:可以多翻翻abseil, 以及folly劈愚,另外也推薦fmtlib
  • 線程安全的瞳遍、無鎖的數(shù)據(jù)結(jié)構(gòu)、線程池: folly
  • google全家桶:gtest菌羽,gflags, glog, protobuf, grpc

最后掠械,也推薦下kudu這個(gè)項(xiàng)目,里面有自己實(shí)現(xiàn)的一些工具包注祖,以及對(duì)google開源項(xiàng)目中utility的整理猾蒂。

單元測(cè)試

每個(gè)程序員都討厭寫測(cè)試。就我自己而言是晨,我覺的單元測(cè)試的目的有以下幾個(gè):

  • 確保功能的實(shí)現(xiàn)和預(yù)期一致
  • 防止程序在重構(gòu)的時(shí)候出問題
  • 給模塊的使用者肚菠,提供使用示例

值得一提的是,對(duì)于C++項(xiàng)目署鸡,除了功能性測(cè)試之外案糙,你最好還能讓你的單元測(cè)試通過一些自動(dòng)化工具的檢測(cè)限嫌,如:

寫在最后

自己的整理這些內(nèi)容時(shí)时捌,腦子里反復(fù)縈繞的一個(gè)問題是:我們?cè)陂_發(fā)一個(gè)項(xiàng)目時(shí)怒医,所要遵守的各種流程和規(guī)范到底是不是真的有必要的?說的更直白一點(diǎn)就是奢讨,“代碼潔癖”這東西到底有沒有意義稚叹?

我的看法是:代碼潔癖不是一個(gè)原則,而是在投入和產(chǎn)出上的一種權(quán)衡拿诸。如果僅僅快速試錯(cuò)扒袖,那么就不需要維持代碼潔癖,因?yàn)槟阃耆恢滥憬裉鞂懙拇a究竟能存活多久亩码。而如果是一個(gè)馬拉松式的項(xiàng)目季率,代碼潔癖就值得維持,因?yàn)樗鼘?duì)于項(xiàng)目的維護(hù)的確很有意義描沟。

最后飒泻,貼一個(gè)自己比較喜歡的C++博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吏廉,一起剝皮案震驚了整個(gè)濱河市泞遗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌席覆,老刑警劉巖史辙,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異佩伤,居然都是意外死亡聊倔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門畦戒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來方库,“玉大人,你說我怎么就攤上這事障斋∽萘剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵垃环,是天一觀的道長邀层。 經(jīng)常有香客問我,道長遂庄,這世上最難降的妖魔是什么寥院? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮涛目,結(jié)果婚禮上秸谢,老公的妹妹穿的比我還像新娘凛澎。我一直安慰自己,他們只是感情好估蹄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布塑煎。 她就那樣靜靜地躺著,像睡著了一般臭蚁。 火紅的嫁衣襯著肌膚如雪最铁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天垮兑,我揣著相機(jī)與錄音冷尉,去河邊找鬼。 笑死系枪,一個(gè)胖子當(dāng)著我的面吹牛雀哨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗤无,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼震束,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了当犯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤割疾,失蹤者是張志新(化名)和其女友劉穎嚎卫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宏榕,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拓诸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了麻昼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奠支。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抚芦,靈堂內(nèi)的尸體忽然破棺而出倍谜,到底是詐尸還是另有隱情,我是刑警寧澤叉抡,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布尔崔,位于F島的核電站,受9級(jí)特大地震影響褥民,放射性物質(zhì)發(fā)生泄漏季春。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一消返、第九天 我趴在偏房一處隱蔽的房頂上張望载弄。 院中可真熱鬧耘拇,春花似錦、人聲如沸宇攻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尺碰。三九已至挣棕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亲桥,已是汗流浹背洛心。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工京闰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喜滨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓贴捡,卻偏偏與公主長得像番枚,于是被迫代替她去往敵國和親法严。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,166評(píng)論 25 707
  • 用兩張圖告訴你葫笼,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料深啤? 從這篇文章中你...
    hw1212閱讀 12,730評(píng)論 2 59
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,982評(píng)論 3 119
  • 我是展鵬教育的大邢老師呈昔,這是我加入日記星球的第21篇原創(chuàng)日記。 今天展鵬教育旗下的展鵬作文友绝、佳一數(shù)學(xué)秋季班課程全部...
    大邢老師閱讀 338評(píng)論 0 2
  • 兒子最近太沉迷于手機(jī)堤尾,我有點(diǎn)不高興,問題:你是想媽媽還是想媽媽的手機(jī)啊迁客,他說:我是想你這個(gè)人郭宝,于是摟著我的脖子,開...
    薇薇shaw閱讀 123評(píng)論 0 0