編譯生成的h.gch文件是什麽鬼?
所謂預編譯頭,就是把頭文件事先編譯成一種二進制的中間格式,供後續的編譯過程使用。GCC編譯頭文件後的中間文件是*.gch。
如何將頭文件編譯為.gch文件呢?用g++編譯,格式:
g++ xxx.h
把.h文件當成.cpp文件一樣來編譯。如果需要控制編譯細節,比如常量定義之類,可加上其它選項。運行之後,會在同個目錄裏生成一個名叫xxx.h.gch的文件。
註意在編譯.gch的過程中,GCC並沒有使用環境變量或 -I 選項來查找被編譯的頭文件,被編譯的頭文件必須在當前目錄下。然而,被編譯的頭文件所進一步包含的其它頭文件,卻可以通過以上途徑找到。簡言之,就是把直接編譯的那個頭文件以類似對待.cpp文件的方式處理了。
比如該如何編譯iostream呢?方法是在當前目錄裏建立一個頭文件,把它放到用戶定義的頭文件裏,比如foo.h,在其裏面寫上:#include <iostream>,然後編譯它:g++ foo.h。生成的foo.h.gch,就是我們要的了。其它文件需要用到iostream的,不要包含iostream,要包含foo.h。切記,不是去包含foo.h.gch!
使用過程中,照搬一些stdafx.h相關的註意事項,它們同樣適用於.gch文件:應該把那些不常修改的(首當其沖,當然是系統的)頭文件放在預編譯頭裏,而那些屬於你的程序的一部分的頭文件,一般並不放在預編譯頭裏,因為它們可能隨時要被修改的。每修改一次就要重新生成預編譯頭,並沒有速度優勢可言,失去預編譯頭的意義了。另外重要的註意事項是:如果你生成預編譯頭的時候用了一些選項,比如宏定義,那麽使用這個預編譯頭的其它源代碼文件,被編譯的時候也要使用這些選項,否則會因為不匹配而編譯失敗。
使用預編譯後的文件時,只要包含其所對應的.h文件即可!比如頭文件叫foo.h,另外有一大堆其它文件都包含了這個foo.h,原來沒有使用預編譯頭技術,現在忽然想使用了,於是把foo.h編譯成了foo.h.gch。那其它文件要做怎樣的修改?——什麽都不用,一切照舊!聰明的GCC編譯器在查找一個.h文件之前,會自動查找其目錄裏有沒有對應的.gch文件,如有,且可用,則用之;沒有,才用到真正的.h頭文件。——慢著,“如有,且可用”,什麽叫“可用”?——就是指這個.gch格式要正確,版本要兼容,而且如上所述,編譯兩者要用同樣的選項。如果.gch不可用,編譯器會給出一條警告,告訴我們:這個預編譯頭不能用!我只好用原有的.h頭文件啦!什麽?你說看不到這個警告?——當然,要先打開 -Winvalid-pch 選項才行,其默認是關閉的。
用 -H 選項感受一下預編譯頭的清爽吧!再沒有滾不完的頭文件了,明顯提高的速度,絕對會讓你有種翻身解放的感覺,原來MinGW也可以和蝸牛般的速度說再見的。
編譯生成的h.gch文件是什麽鬼?