[英]GCC and Precompiled Headers
在閱讀了這篇不錯的文章(預編譯頭的維護和供給)后,我對這些如何在現實生活中實際工作產生了一些疑問。 更具體地說,我怎么知道我需要在以下場景中觸發預編譯頭的重建:
#define
一些東西,它改變了預處理器解釋一些已經包含在我的預編譯頭文件中的頭文件的方式#define
sa 特定的預處理器指令改變了預處理器解釋已包含在預編譯頭文件中的頭文件的方式#include
其他標頭時,上一個問題可能會遞歸發生預編譯頭文件的使用是否應該強制執行某種限制性編碼風格,例如將 .cpp 文件中包含的頭文件數量限制為一個,並且永遠不要在 .cpp 文件中#define
東西?
雖然微軟的編譯器可能在預編譯頭文件方面做得不錯(通過應用一些特定於 MS 的伏都教),因為據我所知,它提供了/Yc
和/Yu
選項,這些選項應該為 GCC 做所有的管道工作似乎此功能需要在 Makefile 中進行大量手動工作和創造力,而且我無法找到一個模板來解決使用預編譯頭文件的所有缺陷。
例如,如果我有一個構建多個庫的項目,為了在每次更改后不重建所有庫,我必須在 Makefile 中使用一些非常可愛的sed
技巧來檢測頭文件中的一個#include
d 是否被當前庫已修改(或#include
sa 修改后的標頭)。 我什至不敢考慮預先構建的頭文件實際上意味着構建腳本在每次需要時重建它們的復雜性。
目前GCC(即4.7)和它以前版本的作品很好地與預編譯頭,只有當你有一個共同的頭到你的應用程序,並在需要時即單頭(其中包括把所有的系統的,和圖書館具體的,通過應用程序)是#include
-d (作為您的來源的第一個非注釋詞素)被您的應用程序的每個來源。
所以,你應該有一個單一的yourapp.h
並有充分的源文件(即每編譯單元)的yourapp
開始#include "yourapp.h"
用相同的預處理方案(即-D
或者-I
或-U
的命令)線。 youapp.h
頭文件通常是#include
-ing 許多其他頭文件,例如系統頭文件(或 GTK 或 Qt 頭文件),如<stdlib.h>
或<sys/poll.h>
或 [在 C++ 中] <algorithm>
或<gtk/gtk.h>
或<QtGui>
等。
回想一下, -H
是一個有用的選項,可以讓gcc
告訴您包含的內容。
如果需要,您的源文件可能在#include "yourapp.h"
之后有一些額外的#include
。
在 GCC 包含 [單個] 預編譯頭文件后,您當然可以#define
宏、 #include
一些非預編譯頭文件、使用#ifdef
進行條件編譯等。但該預處理不會被“預編譯” !
這可能不符合您的需求或習慣。
一些人(特別是來自 Google,特別是 Diego Novillo)正在研究PreParsed Header (pph) 分支以改善這種情況,但是當前的 GCC 主干還沒有完成這項工作。
關於 GCC 的這種行為的解釋是預處理頭本質上是整個 GCC 堆的持久序列化檢查點(通過 Ggc 和 GTY 和gengtype
與 GCC 內部的內存管理相關)。 只有當gcc
處於初始空狀態時才能加載該檢查點堆。 一旦gcc
知道某些內容(實際上是cc1
或cc1plus
),它就不能再加載任何預編譯頭文件*.h.gch
並且將恢復解析文本頭文件*.h
。
甚至GCC 4.9 也需要一個單獨的預編譯頭文件。 Diego Novillo 等人的預解析頭文件。 已被放棄。
C++ 標准的未來版本( C++14 之后)可能會定義一個模塊機制。 參見例如n4047提案和C++20標准。
(附加附錄,2020 年夏季)這仍然適用於GCC-10 ,其中存在多個靜態分析器選項。 另請參閱Clang 靜態分析器和這份報告草案。 考慮使用Frama-C 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.