我知道 #inclusion 通常被描述為文本復制粘貼前處理器指令。現在,如果一個標頭被 #include 保護,或者 #pragma 一次,那么我們如何描述從第一個翻譯單元到 #include 所述標頭后實際發生的事情?
uj5u.com熱心網友回復:
沒有“第一個”翻譯單元。所有翻譯單元在概念上都是并行翻譯的(當然,在實踐中,您可能最終一次編譯一個,但這并不重要)。
每個翻譯單元都從一張白紙開始。從技術上講,這并不完全正確,因為您可以#define在命令列中添加s 并且還有一些預定義的宏,但無論如何,沒有翻譯單元會擁有#define在任何其他翻譯單元中執行的s的“記憶” 。因此,#include盡管有保護,標題可能會多次出現。只是它不會#include多次進入單個翻譯單元。
這意味著您仍然必須小心避免多個定義:例如,如果您的標頭包含一個全域變數,那么您必須確保它是const(因此它將具有內部鏈接)或顯式宣告它inline(將所有定義折疊為一個)或extern(抑制標題中的定義,以便您可以將定義放入單個翻譯單元中)。
盡管包含守衛不會阻止跨多個翻譯單元的多個定義,但它們確實阻止了單個翻譯單元中的多個定義,這很重要,因為即使某些物體可能在程式中多次定義,但仍然不允許多個定義出現在同一個翻譯單元中。例如,如果inline標題中有一個全域變數,則多個翻譯單元可以包含該標題,并且這些定義將在鏈接時全部折疊為一個定義,但是如果任何一個翻譯單元定義了該定義,則會出現編譯錯誤多次可變。因此,這樣的頭檔案必須有一個包含保護。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/383739.html
上一篇:pybind11與GetModuleFileName沖突
下一篇:一個模塊中有多少個翻譯單元?
