編譯時間過長注意事項

2021-06-19 22:32:27 字數 3150 閱讀 6618

1、修改標頭檔案後會導致較多的重編譯工作;

2、能放在*.cpp中的include檔案,盡量不要放在*.h中

3、避免標頭檔案重複包含。

下文**

對於乙個中型或者以上專案,編譯時間本來就不短,如果在編碼過程中,一些問題不注意,將使編譯時間更長,下面介紹幾點需要注意的地方。

關於《c++ coding standards》以下幾條整改原則:

關於include的原則最多,因為包含標頭檔案相當於將**複製到本檔案來編譯,而標頭檔案又經常是用來被別人包含的,所以工程檔案多了,每個檔案都有include鏈(包含的檔案又include了其他檔案),該鏈條不會止步 於你工程,而會延伸到你所有使用的第3方庫裡面。

能夠去掉的include就去掉

說明:1.**編寫過程中或多或少都有一些歷史遺留的不必要的標頭檔案包含在你的檔案裡面,找到他們並去掉之。

2.去掉include鏈裡面重複的include。

能夠在cpp裡面include的標頭檔案不要在標頭檔案裡面include。

說明:盡量去掉每個cpp會被串起來的標頭檔案膨脹的機會。

把大多數模組都要使用的庫檔案或者穩定類的標頭檔案include放到預編譯標頭檔案「stdafx.h」裡面

說明:由於預編譯標頭檔案裡面include的內容只會compile一次而被link多次,把一些常用類放到這裡會降低很多編譯時間,但也不能亂來,要點在 於 「大多數」和「穩定」,如果乙個標頭檔案經常變化,他的一次小改動都會引起整個工程rebuild,哪怕只是乙個注釋,因為所有的cpp檔案都包含了 stdafx.h而stdafx.h又包含了這個容易變動的標頭檔案。

想要具體了解可以參考這本書,這本書《c++ coding standards》(英文版)現在在我這裡,另外可以參考《fective c++》關於編譯的章節,這本書在鄒鳴**。

另外可以在繼承關係,如果使用不當,也會產生編譯時間過長的問題,下面這個帖子**c++ faqs關於《我的程式為什麼編譯時間過長》,講解者是bjarne stroustrup

bjarne stroustrup博士,2023年出生於丹麥,先後畢業於丹麥阿魯斯大學和英國劍撟大學,at&t大規模程式設計研究部門負責人, at&t 貝爾實驗室和acm成員。2023年,b. s開始開發一種語言,當時稱為"c with class",後來演化為c++。2023年,ansi/iso c++標準建立,同年,b. s推出其經典著作the c++ programming language的第三版。

你的編譯器可能有問題。也許它太老了,也許你安裝它的時候出了錯,也許你用的計算機已經是個古董。在諸如此類的問題上,我無法幫助你。 

但是,這也是很可能的:你要編譯的程式設計得非常糟糕,以至於編譯器不得不檢查數以百計的標頭檔案和數萬行**。理論上來說,這是可以避免的。如果這是你 購買的庫的設計問題,你對它無計可施(除了換乙個更好的庫),但你可以將你自己的**組織得更好一些,以求得將修改**後的重新編譯工作降到最少。這樣的 設計會更好,更有可維護性,因為它們展示了更好的概念上的分離。

看看這個典型的物件導向的程式例子:

class shape ;

class circle : public shape

// ...

protected:

int radius;

// ...

};class ******** : public shape ;

設計思想是,使用者通過shape的public介面來操縱它們,而派生類(例如circle和********)的實現部分則共享由protected成員表現的那部分實現(implementation)。

這不是一件容易的事情:確定哪些實現部分是對所有的派生類都有用的,並將之共享出來。因此,與public介面相比,protected成員往往要做多 得多的改動。舉例來說,雖然理論上「中心」(center)對所有的圖形都是乙個有效的概念,但當你要維護乙個三角形的「中心」的時候,是一件非常麻煩的 事情——對於三角形,當且僅當它確實被需要的時候,計算這個中心才是有意義的。

protected成員很可能要依賴於實現部分的細 節,而shape的使用者(譯註:user此處譯為使用者,指使用shape類的**,下同)卻不見得必須依賴它們。舉例來說,很多(大多數?)使用 shape的**在邏輯上是與「顏色」無關的,但是由於shape中「顏色」這個定義的存在,卻可能需要一堆複雜的標頭檔案,來結合作業系統的顏色概念。 

當protected部分發生了改變時,使用shape的**必須重新編譯——即使只有派生類的實現部分才能夠訪問protected成員。

於是,基類中的「實現相關的資訊」(information helpful to implementers)對使用者來說變成了象介面一樣敏感的東西,它的存在導致了實現部分的不穩定,使用者**的無謂的重編譯(當實現部分發生改變時), 以及將標頭檔案無節制地包含進使用者**中(因為「實現相關的資訊」需要它們)。有時這被稱為「脆弱的基類問題」(brittle base class problem)。

乙個很明顯的解決方案就是,忽略基類中那些象介面一樣被使用的「實現相關的資訊」。換句話說,使用介面,純粹的介面。也就是說,用抽象基類的方式來表示介面:

class shape ;

class circle : public shape

point center() const

// ...

protected:

point cent;

color col;

int radius;

// ...

};class ******** : public shape ;

現在,使用者**與派生類的實現部分的變化之間的關係被隔離了。我曾經見過這種技術使得編譯的時間減少了幾個數量級。

但是,如果確實存在著對所有派生類(或僅僅對某些派生類)都有用的公共資訊時怎麼辦呢?可以簡單把這些資訊封裝成類,然後從它派生出實現部分的類:

class shape ;

struct common ;

class circle : public shape, protected common

point center() const

// ...

protected:

point cent;

int radius;

};class ******** : public shape, protected common ;

pcie編譯時候注意事項

鍵入以下命令 set path path c xilinx 12.2 ise ds ise bin nt 64bit作業系統請將nt改為nt64 這是乙個已經設定好環境變數的cmd視窗 按照文件繼續執行 等待硬體編譯完成 編譯完成後可以在c sp605 pcie s6 pcie v1 3 imple...

Android編譯注意事項

1 make bootimage 編譯生成kernel.img和boot.img的整合 會在out目錄下生成以下檔案。target ram disk out target product em t8350 emmc ramdisk.img target boot image out target p...

PHP FPM編譯注意事項

configure prefix usr local php 32bit with apxs2 usr local apache2 32 bin apxs with zlib with gd enable mbstring with mysql usr local mysql5 32bit with...