2015-05-09 7 views
15

Ho letto il codice sorgente dcmtk, e trovarono un commento in ofstdinc.h:Quali tipi di file di intestazione non devono essere protetti contro l'inclusione multipla?

// this file is not and should not be protected against multiple inclusion 

e quali tipi di file di intestazione NON DOVREBBE essere protetti contro inclusione multipla?

+1

Quelli che sono cercando di usare un hack (inclusione multipla) per risolvere un problema. Nel tuo nuovo codice, è meglio cercare di evitare questo tipo di soluzione e utilizzare sempre le protezioni incluse. – pmg

risposta

12

Preprocessore metaprogrammazione. Cioè, usando il file incluso come una sorta di funzione in fase di compilazione che esegue alcune attività. Gli argomenti della funzione sono macro. Ad esempio, il file si è collegato ha una sezione simile alla seguente:

// define INCLUDE_STACK to include "ofstack.h" 
#ifdef INCLUDE_STACK 
#include "dcmtk/ofstd/ofstack.h" 
#endif 

Quindi, se ho voluto includere "ofstack.h", lo farei in questo modo:

#define INCLUDE_STACK 
#include "ofstdinc.h" 
#undef INCLUDE_STACK 

Ora, immagino che in seguito lungo la linea, qualcuno vuole usare questa particolare sezione della testata:

// define INCLUDE_STRING to include "ofstring.h" 
#ifdef INCLUDE_STRING 
#include "dcmtk/ofstd/ofstring.h" 
#endif 

in modo da fare il seguente:

#define INCLUDE_STRING 
#include "ofstdinc.h" 
#undef INCLUDE_STRING 

Se "ofstdinc.h" includeva protezioni, non verrebbe incluso.

+0

Nelle istanze di tali intestazioni che ho visto (tipicamente usate per incollare i corpi di enumerati come nell'altra risposta), il '# undefs' era all'interno dell'intestazione stessa. Non era quindi necessario duplicare il codice '# undef''ing ovunque venga usata l'intestazione, ed è impossibile dimenticarsene accidentalmente. –

0

Quasi sempre si desidera proteggere contro l'inclusione multipla. L'unica volta che non vuoi farlo è se stai facendo un po 'di cose fantastiche con i macro C e quindi vuoi avere più inclusioni per ottenere la generazione del codice che desideri (non avere un esempio di questa versione).

+0

Puoi mostrarmi un esempio? Grazie! – sfz

12

Un esempio sono i file di intestazione che prevedono la definizione di una macro. Si consideri un colpo di testa m.h con

M(foo, "foo") 
M(bar, "bar") 
M(baz, "baz") 

Questo può essere usato in qualche altro colpo di testa in questo modo:

#ifndef OTHER_H 
#define OTHER_H 

namespace other 
{ 
    enum class my_enum 
    { 
#define M(k, v) k, 
#include "m.h" 
#undef M 
    }; 

    void register_my_enum(); 
} 

#endif 

e in qualche altro file (possibilmente implementazione):

#include "other.h" 

namespace other 
{ 
    template< typename E > 
    void register_enum_string(E e, const char* s) { ... } 

    void register_my_enum() 
    { 
#define M(k, v) register_enum_string(k, v); 
#include "m.h" 
#undef M 
    } 
} 
+1

FWIW, queste cose sono talvolta note come [macro X] (https://en.wikipedia.org/wiki/X_Macro). –

Problemi correlati