2009-10-31 9 views
321

Mi è stato vedere il codice come questo di solito l'inizio del file di intestazione:Perché #ifndef e #define sono usati nei file di intestazione C++?

#ifndef HEADERFILE_H 
#define HEADERFILE_H 

E alla fine del file è

#endif 

Qual è lo scopo di tutto questo?

+22

+1 - Anch'io ho avuto lo stesso dubbio, e ho ottenuto molte più buone risposte qui, può essere utile per i futuri visitatori: http://stackoverflow.com/q/3246803/1134940 –

+5

Voglio aggiungere a questo che è possibile usa anche ** # pragma una volta **, questo è tutto ciò che devi fare e ha lo stesso scopo di ifdef. Per un confronto tra i due, vedere: http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards – Dimension

+2

Meglio menzionare cosa sia un '# pragma': attiva una caratteristica specifica del compilatore. Sebbene '#pragma once' è * molto * ampiamente supportato, non è standard. – Potatoswatter

risposta

369

Questi sono chiamati #include guards.

Una volta inclusa l'intestazione, controlla se è stato definito un valore univoco (in questo caso HEADERFILE_H). Quindi se non è definito, lo definisce e continua al resto della pagina.

Quando il codice viene incluso di nuovo, il primo ifndef non riesce, risultando in un file vuoto.

Ciò impedisce la doppia dichiarazione di qualsiasi identificatore come tipi, enumerazioni e variabili statiche.

+3

Mmm interresting. Una volta ho interrotto VC++ perché mi ha dato errori riguardo alle doppie definizioni.Non importa, sono un programmatore Objective-C ora =) –

+0

Koning Baard XIV: VC ha anche un '#pragma once' che fa lo stesso :-) – Joey

+63

Inoltre impedisce le inclusioni ricorsive ... Immagina" alice.h "include" bob.h "e" bob.h "include" alice.h "e non hanno guardie incluse ... –

21
#ifndef <token> 
/* code */ 
#else 
/* code to include if the token is defined */ 
#endif 

#ifndef verifica se il dato token è stato #defined in precedenza nel file o in un file incluso; in caso contrario, include il codice tra esso e il #else di chiusura o, se non è presente #else, la dichiarazione #endif. #ifndef viene spesso utilizzato per rendere i file di intestazione idempotenti definendo un token una volta che il file è stato incluso e controllando che il token non sia stato impostato nella parte superiore del file.

#ifndef _INCL_GUARD 
#define _INCL_GUARD 
#endif 
+3

Gli identificativi che iniziano con un carattere di sottolineatura sono riservati; non dovresti definirli da soli. Usa qualcosa come '#ifndef H_HEADER_NAME'. –

+5

So che questo è un vecchio commento, ma in realtà la restrizione di sottolineatura si applica solo a "identificatori esterni" - identificatori che potrebbero finire nella tabella dei simboli dell'oggetto compilato, cioè variabili globali e nomi di funzioni. Non si applica ai nomi macro. – Stu

+1

Il commento di Stu è vero? Ho appena letto https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier e ora non ne sono così sicuro. – Will

2

Ciò impedisce l'inclusione multipla dello stesso file di intestazione più volta.

#ifndef __COMMON_H__ 
#define __COMMON_H__ 
//header file content 
#endif 

Supponiamo di aver incluso questo file di intestazione in più file. Quindi la prima volta __COMMON_H__ non è definito, verrà definito e incluso il file di intestazione.

La prossima volta che __COMMON_H__ è definito, quindi non includerà di nuovo.

Problemi correlati