簡體   English   中英

需要澄清#ifndef #define

[英]Need clarification on #ifndef #define

我正在工作的代碼具有針對不同類face.cc, face.hh, cell.cc, cell.hh edge.cc edge.hh多個類的頭文件和源文件,並且頭文件包含這樣的內容,

#ifndef cellINCLUDED
#define cellINCLUDED

#ifndef faceINCLUDED
#define faceINCLUDED

我通過http://www.cplusplus.com/forum/articles/10627/進行了查看,並發現編寫包含保護的方法是

#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__

因此,在我正在處理的上述代碼中,編譯器是否會自動理解它正在尋找face.hhcell.hh文件?

更好的問題:是寫__CELL_H_INCLUDED__一樣cellINCLUDED

 #ifndef __MYCLASS_H_INCLUDED__ #define __MYCLASS_H_INCLUDED__ 

因此,在我正在處理的上述代碼中,編譯器是否會自動理解它正在尋找face.hh或cell.hh文件?

不,編譯器不會自動理解您的意思。

真正發生的是,在編譯翻譯單元時 ,編譯器會保存一個全局定義的MACRO列表。 因此,您正在定義MACRO __MYCLASS_H_INCLUDED__如果尚不存在)。

如果定義了該宏,則實際編譯器將不會解析直到#endif為止的#ifndef 因此,您可以測試該MACRO的存在,以確定編譯器是否已解析該頭文件以將其僅一次包含在轉換單元中...這是因為編譯器將每個轉換單元編譯為一個展平文件(合並后)所有#includes

參見https://en.wikipedia.org/wiki/Include_guard

正在寫__CELL_H_INCLUDED__一樣cellINCLUDED

是的,這是...。某些人偏愛將帶下划線的前綴和后綴的MACRO用作包含保護的原因是,因為它們被用作標識符的可能性極低...但是, 下划線可能會與編譯器發生沖突 ...

我喜歡這樣的東西: CELL_H_INCLUDED

如果使用cellINCLUDED ,則有一天可能會有人將其用作該翻譯單元中的標識符

預處理程序定義沒有特殊含義。 唯一的要求是它們在模塊之間保持唯一,這就是文件名通常是模塊一部分的原因。

特別是,防止雙重包容的機制並沒有“用”這種語言,而只是使用預處理器的機制。

話雖如此,如今每個值得關注的編譯器都支持#pragma once ,您可能會對此感到滿意。

正如您所引用的鏈接所說,“編譯器沒有自己的大腦”-因此,要回答您的問題,不,編譯器無法理解涉及到哪些特定文件。 它甚至不了解'__cellINCLUDED'在概念上與特定文件有關。

相反,包含保護只是簡單地防止多次重復包含在其打開#ifndef和關閉#endif之間包含的邏輯。 ,作為程序員,告訴編譯器不包括代碼多次-編譯器沒有做任何事情“智能”上一把。

是的,這實際上是告訴編譯器/解析器,如果它已經被放入程序中,則不要被加載。

該文件應位於.h文件的頂部(底部帶有#endif)。

假設您有mainProgram.cpp和Tools.cpp,其中每個文件都加載fileReader.h。 在編譯器編譯每個 cpp文件時,它將嘗試加載fileReader.h。 除非您不告訴它,否則它將兩次加載所有fileReader文件。

ifndef =如果未定義

因此,當您使用這些代碼(以及.h文件中所有代碼之后的#endif)時,您會說:

if not defined: cellINCLUDED
then define: cellINCLUDED with the following code:
[code]
end of code

因此,這樣一來,當第二次將代碼加載到.h文件中時,它將命中if定義位,並第二次忽略該代碼。

這減少了編譯時間,也意味着如果您使用的是較舊/較舊的編譯器,則不會嘗試再次插入代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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