2014-02-18 105 views
6

我已經搜索了一些關於 #pragma一次 究竟做了什麼的一些說明,並且找不到我仍然有些問題的確切答案。需要一些#pragma一次的說明

是否 #pragma once 確保它所包含的頭文件僅被調用一次以及包含在所述頭文件中的頭文件尚未包含在內?另外,如果它只被調用一次,這是否意味着一個.cpp文件,需要一個特定的標題將無法訪問它?如果頭文件標有 #pragma一次 幷包含在.cpp中,那麼該頭文件是否可以在其他地方再次使用?

這些是我沒有找到的澄清的種類。對不起,如果有文件澄清這個地方,但我真的找不到足夠具體的東西。

+2

請注意,雖然普遍支持,但它在技術上不是標準。 – chris

回答

5

#pragma once只在單個翻譯單元中保護單個文件,不包括其包含的子層次。 (但是,如果文件的第二個包含被阻止,則它沒有機會雙重包含任何其他內容。)

您仍可以從另一個.cpp再次包含它。

該文件通常由其inode號碼標識。

請注意,#pragma once是嚴格非標準的,並且大多數仍然喜歡傳統的#ifndef標頭警衛。

+0

這可以幫助我一點,因爲我正在與directX一起玩耍,所以代碼首先不是平臺移動。 我想我現在需要了解的是,翻譯單位是什麼,我敢打賭,它是有據可查的,還有編譯器的具體情況? – NanoTree

+2

@ManicCure,簡單來說,它是一個(cpp)文件,並且所有的頭文件都直接或間接包含在其中。如果你想要一個標準的定義,*這個國際標準中的程序文​​本保存在稱爲源文件的單元中。源文件 連同所有的頭文件(17.6.1.2)和包含的源文件(16.2)通過預處理指令 #include,少於任何有條件包含(16.1)預處理指令跳過的任何源行,被稱爲 翻譯部門。* – chris

3

#pragma once導致當前源文件在一次編譯中只包含一次。 它基本上和#include衛兵相似。

+0

好的,那麼,你能幫我理解一下彙編是什麼嗎?因爲這聽起來對我來說就是編譯器會忽略同一個頭文件的所有包含,即使它可能是需要的,並且不會導致編譯器錯誤,從而導致編譯器錯誤。困惑?我知道我是... #包括警衛有非常明顯的邏輯; #pragma曾經不是因爲編譯器所採取的行動沒有傳達給代碼讀者。 – NanoTree

2

是否#pragma確保它所包含的頭文件僅被調用一次以及包含在所述頭文件中的頭還沒有被包含?

該編譯指示不影響其他標題。如果帶有雜注'a.h'的頭部包含'b.h',則可以通過第三個頭部或直接再次包含'b.h'。

此外,如果它只被調用一次,這是否意味着一個.cpp文件,需要一個特定的標題將無法訪問它?

你可以在任何你想要的地方包括標題,儘可能多的時候,你認爲合適。

如果頭文件被標記爲#pragma一次幷包含在.cpp中,那麼該頭文件是否可以在其他地方再次使用?

是的,這是標頭的正常做法。


哪裏有問題?

如果您確實需要多次包含標頭,並且每個包含都執行不同的操作,不要使用一次編譯指示或一個哨兵宏。這些情況並不常見。

pragma once的好處是它可以幫助您避免錯誤發生,例如有2個頭文件偶然具有相同的哨兵宏。當2個頭文件具有相同的文件名和相同的宏名稱編碼風格時,可能會發生這種情況。

+0

在since文件中,#pragma曾經可以包含在您創建的每個頭文件中,並且您將永遠不會遇到未聲明的標識符的問題,假設您包含所有正確的文件? – NanoTree

+1

@ManicCure'一次編譯指示'只能防止重複的聲明。包括所有正確的文件是棘手的部分。問題是,如果包含太多的錯誤依賴關係,C++可能會變慢。 – Potatoswatter

+1

沒錯。如果你想要更好的編譯速度,請閱讀預編譯頭文件。但那是另一個問題。 – egur