關於預編譯頭

一、什麼是預編譯頭?

預編譯頭物理上與通常的的.obj文件是一樣的,但編譯入預編譯頭的.h,.c,.cpp文件在整個編譯過程中,只編譯一次,如預編譯頭所涉及的部分不發生改變的話,在隨後的編譯過程中此部分不重新進行編譯。進而大大提高編譯速度,並便於對頭文件進行管理,也有助於杜絕重複包含問題。

二、什麼時候使用預編譯頭?

當大多.c或.cpp文件都需要相同的頭文件時。

當某些代碼被大量重複使用時。

當導入某些不同庫都有實現的函數,併產生混亂時。

三、預編譯頭所涉及的編譯開關及使用方法(for msvc)

1、自動預編譯:由編譯器決定什麼時候建立和使用預編譯頭。

編譯參數:-YX。使用此參數缺省時建立以VCxy.pch命名的預編譯頭文件。其中x,y是vc的版本號。可以用-Fp指定pch文件的輸出路徑和文件名。

比如:cl c YX Fp“precomp.pch” **將在當前目錄下生成precomp.pch的預編譯頭文件。**代表源文件。

2、手動預編譯:

    編譯參數:

-Yc預編譯的頭文件的名字 此時缺省建立與頭文件同名的預編譯頭文件。如要該爲其他名字,可使用-Fp選項。

    比如:cl c Ycprecomp.h ** 將建立precomp.pch的預編譯頭文件。

 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    -Yu 預編譯的頭文件的名字  表示在某個源文件時使用此預編譯頭,而不在進行重新編譯。比如:

    cl c Yuprecomp.h **

    注:相應預編譯頭必須在前面已建立過。

 

四、在makefile中簡單的使用預編譯技術

 

obj/i386/debug.obj: debug.c debug.h

        $(CC) Ycprecomp.h -Fo$@ debug.c

        

obj/i386/OperateReg.obj: OperateReg.c OperateReg.h

        $(CC) Yuprecomp.h -Fo$@ OperateReg.c

       

obj/i386/WaterMark.obj: WaterMark.c WaterMark.h

        $(CC) Yuprecomp.h -Fo$@ WaterMark.c 

以下同。

其中precomp.h爲想預編譯的頭文件。

 

五、關於預編譯頭的一些複雜的使用方法

如:

cl -c -Yc"stuff.h" -Fplevel1.pch level1.cpp       -------------(1)

cl -c -Yu"stuff.h" -Fplevel1.pch -Yc level2.cpp   --------------(2)

level2.cpp的開始是這樣的,其中 #pragma hdrstop 表示預編譯結束,所以說代碼也可以放入預編譯頭。

#include "stuff.h"

#include "morestuff.h"

#pragma hdrstop("level2.pch")

(1)       建立使用stuff.h 重命名爲level1.pch的預編譯頭。

(2)       在從stuff.h建立的預編譯頭level1.pch的基礎上,參考level2.cpp建立另一個預編譯頭level2.pch

此時的命名規則參見Yc無參數時的使用方法。

 

預編譯頭的其他使用細則請參考msdn。

 

附:

1、  預編譯與guard宏

這是兩個根本沒有關係的概念,如果說非要找出相同的地方,那就是預編譯頭對控制重複包含也有一定的幫助。

#ifndef _PLOTBRUSH_

#define _PLOTBRUSH_

---

#endif  // _PLOTBRUSH_

這種guard宏是防止在同一個.c文件中把同一個.h文件包含兩次。

即防止出現

#include <windows.h>

#include <windows.h>

的情況的。

而預編譯頭相當於在全局的角度,來控制那些部分僅被編譯一次的問題。

guard宏只對當前編譯單元有效。在1.c中定義了_PLOTBRUSH_對2.c是根本沒影響的。

 

2、  98ddk中build 時,使用build –Z將只編譯有改變的源文件。-c 起清除目標文件夾的作用。

如有錯漏請指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章