簡體   English   中英

GCC 和預編譯頭文件

[英]GCC and Precompiled Headers

在閱讀了這篇不錯的文章(預編譯頭的維護和供給)后,我對這些如何在現實生活中實際工作產生了一些疑問。 更具體地說,我怎么知道我需要在以下場景中觸發預編譯頭的重建:

  • 我決定在我的一個 .cpp 文件中#define一些東西,它改變了預處理器解釋一些已經包含在我的預編譯頭文件中的頭文件的方式
  • 我在我的一個 .cpp 文件中包含另一個頭文件,該文件#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知道某些內容(實際上是cc1cc1plus ),它就不能再加載任何預編譯頭文件*.h.gch並且將恢復解析文本頭文件*.h


附錄(2014 年 11 月及之后)

甚至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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM