農林漁牧網

您現在的位置是:首頁 > 農業

c++20模組系統強勢來襲

2022-08-15由 cpp旺哥 發表于 農業

support files是什麼意思

今天向大家介紹c++20核心語法modules,從c++11到今天的c++20,這是c++不斷推陳出新從量變到質變的過程。在介紹modules之前,我們先來了解include機制。

include機制

c++為了完全相容c語言,讓c語言開發者快速學習c++語言,因此繼承了c語言的include機制。include是包含的意思,就是將標頭檔案的所有內容複製過來,#則代表預處理的意思,相關的預處理還有#ifdef、#endif,在此就不做過多的介紹。

c++將程式碼分為標頭檔案和cpp原始檔,標頭檔案主要是申明函式等相關介面,cpp檔案則是具體實現。開發者可以將cpp檔案編譯成lib檔案,使用者無需關係其具體的實現,這樣能很好的將實現邏輯和介面分離。

編譯單元

:當一個c或cpp檔案在編譯時,預處理器首先遞迴包含標頭檔案,形成一個含有所有必要資訊的單個原始檔,這個原始檔就是一個編譯單元。

在同一個編譯單元裡,重複包含標頭檔案會照成重複定義的問題,例如:一個頭檔案定義了一個class(不是申明),然後在一個cpp檔案中包含兩次,編譯器就會報“型別重定義”錯誤。為了解決這一編譯錯誤問題,必須要在標頭檔案裡寫上#ifndef、#define 和 #endif(新版編譯器你可以#pragma once),但大多數人認為這一解決辦法並不完美。同時還需要保證include的順序問題,多個頭檔案中的宏定義順序關聯問題,必須要按照順序包含標頭檔案。

c++編譯慢是公認的,你會發現編譯一個工程的時間足夠幹很多事情,其中有一大部分原因就是include照成的。一個公共的標頭檔案很可能被N個編譯單元包含,這N個編譯單元都會去編譯標頭檔案,尤其是修改這個公共標頭檔案,再編譯簡直讓人慾哭無淚,準確的詮釋了“牽一髮而動全身”。

c++20模組系統強勢來襲

C++不適應在大規模程式設計與現代開發中的應用環境,越來越多的模板的使用,已經導致了編譯時可伸縮性和程式設計師生產力的嚴重障礙。它構建效能低下,與雲和分散式構建的整合性差。此外,嚴重依賴標頭檔案包含(即從編譯器的角度複製程式碼)和宏扼殺了C++開發人員的開發。

在c++中每個cpp都單獨編譯,最後將他們連結在一起,由於每個編譯單元都是獨立編譯的,導致各個編譯單元無法溝通,採用標頭檔案建立各個編譯單元的橋樑,標頭檔案中描述介面的資訊。那麼有沒有一種替代標頭檔案的方式?將申明和實現放在一個檔案中,介面資訊交給編譯器自動生成?答案是肯定的,請讀者繼續往下看。

可以看出include的機制有一系列問題,這些問題總是不盡人意,曾經有多少人抱怨include機制太爛,又有多少人為此轉移陣營而投靠其它語言。面對標準委員會的一次又一次推移,最終module特性凍結在c++20。

modules重磅來襲

為了解決以上系列問題,c++20 modules應運而生!(手動特效:金光閃閃)

c++20模組系統強勢來襲

c++20模組系統強勢來襲

其中,WG21官方的n4465。pdf文件對modules的目標描述:

1。 componentization;

2。 isolation from macros;

3。 scalable build;

4。 support for modern semantics-aware developer tools。

gcc官方對其描述:

Reduce build times due to not reparsing large header files

Proper interface/implementation isolation

Harder to have ODR violations

mvc、gcc、clang 三大編譯器基本已完成c++17的開發工作,目前正在開發c++20核心功能。gcc編譯器很早就建立了module分支,可以從gcc官網看到,2017年3月1日 第一個模組可執行檔案執行。mvc已經開始試驗性的支援module,可以從微軟官方c++部落格看到,vs2015就開始支援modules了,我相信正式版本將很快與我們見面。

開始modules工作

如果您使用的是Visual Studio 2017 15。3之前的版本,請新增/experimental:module /module:stdIfcDir “$(VCToolsInstallDir_150)ifc\$(PlatformTarget)”到`` 配置屬性‘’-> `` C / C ++‘’->``命令列‘’以開啟該專案的模組。

(我的版本是vs2017 15。9。7 ,所以我直接跳過上一步)接下來,專案屬性頁->c/c++->語言->c++語言標準選擇“最新草案標準(/std:c++latest)”,啟用c++模組(實驗性)選擇“是”。

c++20模組系統強勢來襲

c++20模組系統強勢來襲

以上是stl的modules示例,微軟官方提供的std模組參考如下

std。regex 提供標題的內容

std。filesystem 提供標題的內容

std。memory 提供標題的內容

std。threadingprovodes頭部的內容

std。core 提供C ++標準庫中的所有其他內容

自定義模組

新建Mo。ixx檔案(注意字尾名的變化),然後我們需要在main函式前匯入MO模組(import MO;)並使用它,需要注意的是隻有標記export的才會被匯出,否則外部無法呼叫。我們可以在模組中匯入子模組,可以用大括號批次export,也可以更小粒度的控制export。

c++20模組系統強勢來襲

編譯它會生成兩個檔案,分別是obj和ifc。obj我們並不陌生,那麼ifc是個什麼東西?其實它是模組的二進位制描述檔案,無法手動更改,雖然沒有了標頭檔案,但是需要一個ifc檔案,讓編譯器知道介面資訊,用於和其它TU建立橋樑。可以看到模組直接被當做TU處理,無論你有多少個編譯單元import該模組,都不會重複編譯,大大提高了編譯速度,是不是很酷!

c++20 module 將是一個全新的開始,所帶來改變是巨大的,這些改變是不言而喻的,從這一刻開始構建你的大型專案。好吧,我們扔掉include,從modules開始,更快的構建速度,更清爽的程式碼架構,更小的功能依賴,更好的獨立元件,像c#一樣高效而優雅的開發。

另外大家可以查閱clang官方文件,其中關於c++20modules的詳細介紹。同時clang提供了c++模組對映工具,可以將以前的標頭檔案快速對映成現代c++的模組系統。

結束語

modules終於來了!模組對於開發的好處毋庸置疑,我相信這是很多人都有所期待的,那些抱怨include垃圾而轉移陣營的同學,是時候迴歸c++了。

從c++11到c++20,還在用c++98的你,我就問你慌不慌?當下急速發展的網際網路時代,不學習就意味著淘汰,希望大家勇於接受新事物!

對此有任何疑問,歡迎大家留言,謝謝!