本站AI自動判斷提供您所需要的app下載:點我下載安裝,你懂的APP
C++發(fā)展得非常快!例如,C++標準的頁數(shù)從 C++98/03 的 879 頁增加到了 C++20 的 1834 頁,多了近 1000 頁!更重要的是,C++每次修訂后,我們都會獲得幾十個新特性。你需要學(xué)習(xí)所有這些東西才能寫出好代碼嗎?如何在當(dāng)今的 C++世界中保持理智?
介紹你可能知道 C++是一種復(fù)雜的語言。我甚至發(fā)現(xiàn)了一整頁Wiki是講對 Cpp 的批判的。現(xiàn)代 C++甚至為生態(tài)添加了更多內(nèi)容。
以下是我之前提到的規(guī)范頁數(shù)的完整數(shù)據(jù):
C++98/03-879,N1905,2005 年 10 月
C++11-1324,最后草案,N3337,2012 年 1 月
C++14-1368,最后草案,2014 年 11 月
C++17-1586,草案,N4606
C++20-1834,草案,N4861
看起來 C++17 幾乎比 C++98/03“大”了 80%,而 C++的最新草案比 C++03 多了將近 1000 頁。你可以抱怨增加的這些復(fù)雜性,想學(xué)好所有這些東西也很困難。但這有那么可怕嗎?面對這樣的情況,你能做些什么?
首先,我們來看看你在 C++中可能會遇到的一些問題。
一些問題僅舉幾例:
節(jié)奏太慢
節(jié)奏太快
特性的混亂/復(fù)雜性
編譯時間慢
缺乏依賴管理
我們來仔細研究一下。
節(jié)奏太慢2017 年,我們迎來 C++17。雖然每三年就迎來一個新標準是很棒的,但許多開發(fā)人員抱怨新版本并不是每個人都期待的。
很多特性:比如概念(concept)、模塊、范圍(range)、協(xié)程(co-routine)……都沒有被接受,我們至少需要再等三年才能讓它們進入規(guī)范。
在 2020 年,C++20 已經(jīng)準備就緒,并且這些重要特性將隨編譯器一起提供!但我們還是會抱怨合約(contract)還沒加進來,反射(reflection)、執(zhí)行器(executor)或網(wǎng)絡(luò)(networking)仍在討論中。它們可能出現(xiàn)在 C++23 甚至更高版本中。
看起來有些特性接受起來比較慢……而且總有東西值得抱怨。
節(jié)奏太快像往常一樣,我們在這里可能有兩種相互矛盾的意見。盡管對某些人來說升級節(jié)奏很慢,但對其他人來說卻很難跟上變化。
你剛剛學(xué)習(xí)了 C++11/14……現(xiàn)在你就需要更新 C++17 的知識,然后 C++20 就在路上了。三年并不是那么短的時間,但請記住,編譯器一致性、公司政策、團隊指南可能會以不同的節(jié)奏前進。
你的公司是立即更新到最新的 C++版本還是等待幾年?
特性的混淆/復(fù)雜性只需閱讀這條評論:
CallMeDonk:
我喜歡 C++。這是我的首選語言,但你必須承認,它對值類的“大雜燴”實現(xiàn)是很怪異的。包括我在內(nèi)的大多數(shù)程序員更喜歡簡單的、定義明確的語言結(jié)構(gòu),而不是奇怪和復(fù)雜的語法。
C++在各個方面都很清晰嗎?可能不是……
以下是一些可能難以理解并可能讓程序員糊涂的主題:
移動語義移動語義的原則非常明確:不要復(fù)制,而是嘗試“竊取”托管資源的內(nèi)部結(jié)構(gòu),你應(yīng)該獲得不錯的性能提升。但魔鬼都藏在細節(jié)中。
我不會寫很多通用代碼,所以幸運的是,我不必一直考慮移動語義。但是,當(dāng)我遇到 move 和 const 時會很困惑——請參閱我上一篇關(guān)于該主題的文章。我不相信所有 C++開發(fā)人員都會理解這里的規(guī)則。特別是你現(xiàn)在需要記住編譯器生成的六個默認操作:默認構(gòu)造器、析構(gòu)函數(shù)、復(fù)制構(gòu)造器、移動構(gòu)造器、賦值運算符和移動賦值運算符。
Rvalues/xvalues/prvalues……myValues、fooValues最后一個是我編的……但那么多值類別實在太讓人頭疼了!
在 C(或 C++98/03)中,你只需要知道左值與右值,現(xiàn)在它有點微妙了。
不過,問題是你是否需要記住它?
一些不錯的評論:
c0r3ntin:
初始化這很復(fù)雜,但不是每天都能遇到。這個值可以 address 嗎?可以復(fù)制嗎?可以移動嗎?應(yīng)該移動嗎?只有在極少數(shù)情況下,你才需要主動去澄清并充分理解它們。(模板化庫編寫、熱路徑等)。大多數(shù)時候 C++并不比 java 或其他東西復(fù)雜。可悲的是大多數(shù)人都忘了這一點。C++可能是最復(fù)雜的語言,但是你可以編寫非常好的代碼而無需關(guān)心具體的細節(jié)。BigObject o=getBigObject();
現(xiàn)在有 18 種方式(從 C++17 開始)!
參閱:C++中的初始化是瘋狂的;r/cpp線程
模板(和模板推導(dǎo))當(dāng)我看到 C++17 的所有變更時,我很迷茫;關(guān)于模板的細節(jié)太多了。
同樣的情況發(fā)生在 C++20 中,我們迎來了一個重大且期待已久的改進:概念——它徹底改變了 C++。
然而,如果你想學(xué)習(xí)模板,一開始可能會不知所措。
ABI隨著新特性列表的不斷增長,“從頭開始”修復(fù) C++設(shè)計中的舊問題可能是很誘人的主題。但這種語言的原則是不能破壞舊代碼,所以委員會非常嚴格,不喜歡改變已引入特性的路線。
這個問題沒有正確的答案,但無論如何,一個經(jīng)過充分討論的主題要比倉促的舉動更好。
缺乏依賴管理工具我們可以抱怨 C++沒有“交?付”一個很酷的依賴管理系統(tǒng)。但現(xiàn)實情況是,在可預(yù)見的未來,這可能都不會實現(xiàn)。擁有一個“標準”的包管理器是一個艱難的選擇,尤其是它必須處理如此多的可用 C++的平臺和系統(tǒng)。
不夠安全前段時間,你可以讀到提到這個問題的一些文章(這篇和這篇):
谷歌工程師本周表示,Chrome 代碼庫中大約 70%的嚴重安全漏洞是內(nèi)存管理和安全漏洞。
微軟也是如此。由于大部分代碼是 C 或 C++,所以每個人都指責(zé) C++不夠安全。
其他問題?你在這種語言上遇到的主要問題都有哪些?
到目前為止,我們已經(jīng)討論了一些問題……那么如何應(yīng)對它們呢?有機會解決這些問題嗎?
如何保持理智沒有完美的編程語言;每種語言都有一些問題。以下是我關(guān)于如何處理現(xiàn)代 C++問題的建議:
保持樂觀
使用最佳指南
使用最好的工具
跟上最新進展
不要打開引擎蓋
使用你需要的
增量變更
最后的底線:你的舊代碼仍然安全并且可以編譯
保持樂觀,語言在不斷發(fā)展沒有人愿意使用舊的語法和結(jié)構(gòu)來編寫代碼。我們已經(jīng)看到很多關(guān)于 C++11 之前的舊版 C++的抱怨。人們花了將近 13 年的時間(從主要的 C++98 算起,不包括次要的 C++03)才提出新的主要版本:C++11。現(xiàn)在我們可以很高興回到了正軌,每三年都會有一些變化。歸根結(jié)底,你不能說你的語言已經(jīng)死了。
雖然某些特性非常龐大,可能會帶來混亂或需要學(xué)習(xí)更多東西,但實際情況其實很簡單:
在 C++03 之后添加的 1000 個新頁面中的大部分用于標準庫。這意味著你可以使用更多助手和子系統(tǒng),而無需查找第三方庫。這絕對會讓你的生活更輕松。
對于移動語義,你可以依賴庫類型,因為它們會為你完成正確的工作。例如,你現(xiàn)在可以安全地返回std::vector并確保它可能被移動甚至被刪除,而無需額外副本。
至于模板,它變得越來越容易使用。概念讓代碼更安全,沒有像 SFINAE 這樣的技巧。更重要的是,我們有了constexpr和auto,讓泛型代碼更簡單了(幾乎就像常規(guī)代碼一樣)。
至于安全性:在這里查看 C++指南的安全配置文件的自動化工具。C++ Core Check中的新安全規(guī)則|C++團隊博客。我們可以期待新的、更好的工具來執(zhí)行代碼分析甚至檢測,以盡快發(fā)現(xiàn)潛在的安全問題。或者看這篇文章:使用靜態(tài)分析原理縮小Rust和C++之間的差距——SunnyChatterjee——CppCon
使用指南如果你對 C++代碼的許多方面都感到困惑,那么你應(yīng)該查閱 C++核心指南。它由熱心的 C++開發(fā)社區(qū)創(chuàng)建,主要編輯是 Herb Sutter 和 Bjarne Stroustrup。
看這里:
C++核心指南@Github
這里有一個漂亮的網(wǎng)站:
C++核心指南:網(wǎng)站
只需輸入你面臨的問題(例如return value),你就可以輕松找到建議——例如:指南:返回值
使用這些指南將為你節(jié)省大量時間,并且你可以非常快地學(xué)習(xí)一些好的模式。
還有工具!感謝 Clang 以及其他平臺上的開發(fā)速度提升,我們獲得了如下工具:
ClangTidy(以前是 clang-modernise)
Clang Format
Clang Static Analyzer
VisualAssist
Clion/ResharperC++
VisualStudio——像C++ Core Checker這樣的工具
PVS Studio
用于 VisualStudio 的Clang Power Tools
新的C++核心檢查規(guī)則|C++團隊博客
C++核心指南檢查器參考|微軟文檔
介紹vcperf/timetrace,用于C++構(gòu)建時間分析|C++團隊博客
C++ Core Check中的新安全規(guī)則|C++團隊博客——C++和 Rust 一樣安全嗎?
或者查看我關(guān)于其他工具的文章:C++生態(tài)系統(tǒng):編譯器、IDE、工具、測試等
雖然它不像其他語言(主要基于 Java 或基于.NET)那么好,但它正在變得越來越好。請記住,由于 C++語法復(fù)雜,因此很難實現(xiàn)即時分析代碼的工具。
努力跟上最新進展C++社區(qū)非常活躍。有很多博客、書籍、會議……甚至有可能在你所在的城市有本地社區(qū)。
首先,我建議去 isocpp.org 查看所有事件/新聞/文章。然后你可以查看Meeting C++和有關(guān)本地C++小組的信息。還有reddit/cpp,你可以在那里看到一些最棒的 C++故事。
還有CppCast——一個針對 C++開發(fā)人員的每周播客。
并參考以下書籍:
C++編程語言第4版
高效的現(xiàn)代C++
編程:使用C++的原理和實踐
發(fā)現(xiàn)現(xiàn)代C++:科學(xué)家、工程師和程序員的強化課程
C++之旅(C++深入系列)第2版
你還可以查看推薦的 C++資源列表:
Bartek的編程博客:資源
細節(jié)太多了?C++如此強大的原因之一是它允許你實現(xiàn)非常接近底層的代碼。你可以控制所有細節(jié)、內(nèi)存布局、性能優(yōu)化等……同時,這些能力增加了語言的復(fù)雜性。
不過,如果你不需要走那么遠,你可以停留在相對較高的抽象級別。
例如,你不需要編寫可選類型,因為你可以使用標準庫中的std::optional。如果你不想涉及低級別和容易出錯的聯(lián)合類型,你應(yīng)該意識到std::variant是一個安全的選項。
使用你需要的東西C++是一種多范式語言;你可以以多種不同的方式使用它。最近,我讀到了一條有趣的評論,說 Cpp 程序員在不接觸模板元編程甚至異常等高級內(nèi)容的情況下,也能持續(xù)多年表現(xiàn)出色。這在很大程度上取決于項目的代碼風(fēng)格。
例如,即使像谷歌這樣的公司也限制了 C++的特性,比如說他們不使用異常。
如果你不是庫開發(fā)人員,你可能不會遇到自定義移動運算符或移動構(gòu)造器的麻煩。同樣,高級元編程的內(nèi)容也可能不是你的代碼的關(guān)鍵部分。
增量變更如果你是從頭開始或只有一個小的代碼庫,那么轉(zhuǎn)到 C++11/14 應(yīng)該相對容易一些。可是 20 年(或更久!)前開始創(chuàng)建的上百萬行代碼呢?
只需一步一步來就行了。
至少對于新代碼,你應(yīng)該開始使用現(xiàn)代 C++。此外,通過應(yīng)用“童子軍規(guī)則”,你可以改進你所接觸的那些代碼。
這可能會帶來一些混合代碼,但還是比只保留老舊風(fēng)格要好。
最后的底線:你的舊代碼仍然可以編譯C++規(guī)范越來越大的原因之一是該語言向后兼容。所以委員會通常會引入新特性,但很少刪除舊的東西。所以……你的代碼仍然可以編譯。如果你不想前進,不想使用新的東西,那么你還是可以保持當(dāng)前的風(fēng)格。
有時你會收到一些關(guān)于不推薦使用的內(nèi)容或刪除特性的警告(如 C++17 中的auto_ptr),但即使在這種情況下,你也可以將編譯器切換到一些較舊的 C++標準。
總結(jié)這篇文章有一些抱怨,也有一些“美化”。我試圖找出這種語言及其演變過程中存在的各種問題,以及一些積極的改進跡象。雖然我們可以抱怨復(fù)雜性、變化的速度等,但我認為我們不能說這種語言已經(jīng)死掉了。這是好事!:)
我認為你不必快速追逐新特性并立即重寫現(xiàn)有代碼。試著跟上進展,使用真正改進你工作的特性,你的代碼應(yīng)該逐漸改進并變得更加“現(xiàn)代化”(這是可以定義的,請參閱 meetingcpp 的相關(guān)文章)
在采用 C++11/14/17/20 的新特性時,你的方法是什么?
你使用 C++的主要問題是什么?
你在工作中使用現(xiàn)代 C++嗎?
以下是一些常見的C語言靜態(tài)測試工具:
1. Splint:免費的開源靜態(tài)分析工具,支持C程序,可以檢查類型安全、資源泄漏、未初始化變量等常見問題。
2. PC-lint:商業(yè)靜態(tài)分析工具,支持C和C++程序,可以在編譯時或運行時檢查代碼中的問題,例如不兼容的指針類型、內(nèi)存泄漏等等。
3. Clang:C語言的靜態(tài)分析工具,可用于錯誤檢查、代碼重構(gòu)和查找代碼中的重復(fù)。
4. Cppcheck:免費的開源靜態(tài)分析工具,支持多渠道途徑,適用于C和C++程序,可檢查未分配的內(nèi)存、數(shù)組越界、指針使用或數(shù)值溢出等問題。
5. Flawfinder:免費的開源程序,適用于C和C++程序,可以查找常見的安全漏洞、編碼風(fēng)格錯誤和未定義的行為等。
6. Coverity:一種商業(yè)靜態(tài)分析工具,支持多種編程語言,包括C語言,可用于檢查缺陷、安全漏洞和性能問題等。
這些工具可以幫助程序員在代碼開發(fā)周期的不同階段檢測代碼中的錯誤和問題,從而提高代碼質(zhì)量和可靠性。