cpp或者cppcheck


本站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ì)量和可靠性。