2009-03-11 2 views
14

mi sono imbattuto in alcuni codice C in cui l'autore utilizza il seguente idioma tutto il luogo:Che senso ha dire "#define FOO FOO" in C?

typedef __int32 FOO_INT32; 
#define FOO_INT32 FOO_INT32 

Qual è il punto di fare questo? Non dovrebbe essere sufficiente il typedef? È una soluzione alternativa per alcuni stupefacenti compilatori C là fuori?

+0

sentitevi liberi di marcare questa domanda come risposta;) – claf

risposta

28

con l'istruzione #define, sarete quindi in grado di verificare se il typedef è stato fatto da qualche altra parte nel codice utilizzando:

#ifdef FOO_INT32 
FOO_INT32 myfoo; 
#else 
int myfoo; 
#endif 
2

E 'una pratica che a volte è fatto in intestazioni. #define consente il test in fase di compilazione dell'esistenza del typedef. Questo codice consente:

#ifdef FOO_INT32 
FOO_INT32 myfoo; 
#else 
int myfoo; 
#endif 

o come una vera guardia #define, simile alle guardie di file di intestazione.

#ifndef FOO_INT32 
typedef int FOO_INT32 
#define FOO_INT32 FOO_INT32 
#endif 

non è necessariamente una buona pratica, ma ha i suoi usi, soprattutto quando si hanno alcune intestazioni che utilizzano tipi definiti da altre biblioteche, ma si desidera fornire i propri sostituti per i casi in cui non si sta usando quelle librerie a tutti.

+0

stessa risposta di prima ... – user65636

+0

Credo che se ci fossero #ifndef FOO_INT32 poco prima della typedef, avrebbe dovuto indovinare l'uso come guardie. – user65636

+1

Non è assolutamente una buona pratica per il nuovo codice. –

1

Questo modello è utile anche per il rilevamento di funzionalità di registri nei microprocessori, come in this question. Per esempio, ci possono essere due file simili di intestazione, uno dei quali definisce un timer, e quello che definisce 2:

cheapprocessor.h:

#define TMR1 TMR1 
extern volatile int TMR1; 

expensiveprocessor.h:

#define TMR1 TMR1 
extern volatile int TMR1; 
#define TMR2 TMR2 
extern volatile int TMR2; 

che significa nella tua codice principale, quando si include un processor.h generico che delega all'intestazione appropriata per la destinazione, è possibile rilevare funzionalità:

#include <processor.h> 

#ifdef TMR2 
    x = TMR2; 
#else 
    x = 0; // no timer, probably because we're on the cheaper model 
#endif 
1

Un'altra ragione è che uno standard potrebbe richiedere che le definizioni siano macro.

frammento da glibc netinet/in.h:

/* Standard well-defined IP protocols. */ 
enum 
    { 
    IPPROTO_IP = 0, /* Dummy protocol for TCP. */ 
#define IPPROTO_IP  IPPROTO_IP 
    IPPROTO_ICMP = 1,  /* Internet Control Message Protocol. */ 
#define IPPROTO_ICMP  IPPROTO_ICMP 
    IPPROTO_IGMP = 2,  /* Internet Group Management Protocol. */ 
#define IPPROTO_IGMP  IPPROTO_IGMP 

Qui simboli enum sono esportati anche come macro come richiesto dalla the relevant POSIX spec, citando:

L'intestazione deve definire le seguenti macro per l'uso come valori l'argomento di livello di getsockopt() e setsockopt():

IPPROTO_IP

Internet protocol. 

IPPROTO_IPV6

Internet Protocol Version 6. 

...