2009-03-11 19 views
14

me encontré con algunos C código donde el autor utiliza la siguiente expresión idiomática por todo el lugar:¿De qué sirve decir "#define FOO FOO" en C?

typedef __int32 FOO_INT32; 
#define FOO_INT32 FOO_INT32 

¿Cuál es el punto de hacer esto? ¿No debería ser suficiente el typedef? Es una solución para algunos compiladores wonky C por ahí?

+0

dude en marcar esta pregunta como respondida;) – claf

Respuesta

28

Con la instrucción #define, a continuación, será capaz de probar si el typedef se ha hecho en otro lugar en el código usando:

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

Es una práctica que se hace a veces en las cabeceras. El #define permite la prueba en tiempo de compilación de la existencia del typedef. Esto permite código como:

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

o como una verdadera protección #define, similar a las protecciones de archivos de encabezado.

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

No es necesariamente una buena práctica, pero tiene sus usos, especialmente cuando usted tiene algunas cabeceras que utilizan tipos definidos por otras bibliotecas, pero que desea proporcionar a sus propios sustitutos para los casos cuando no se está usando esas bibliotecas en absoluto.

+0

misma respuesta que primero ... – user65636

+0

supongo que si había #ifndef FOO_INT32 justo antes de la typedef, tendría que adivinar el uso como guardias. – user65636

+1

No es una buena práctica para el nuevo código. –

1

Este patrón también es útil para la detección de características de registros en microprocesadores, como en this question. Por ejemplo, puede haber dos archivos similares de cabecera, uno de los cuales define un temporizador, y que define 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; 

lo que significa en su código principal, cuando incluye un genérico processor.h que delega en el encabezado apropiado para el destino, puede detectar características:

#include <processor.h> 

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

Otra razón es que un estándar puede requerir que las definiciones sean macros.

de fragmentos de 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 

Aquí símbolos de enumeración también se exportan como macros como es requerido por the relevant POSIX spec, citando:

La cabecera definirán las siguientes macros para su uso como valores de el argumento de nivel de getsockopt() y setsockopt():

IPPROTO_IP

Internet protocol. 

IPPROTO_IPV6

Internet Protocol Version 6. 

...

Cuestiones relacionadas