2010-06-21 7 views
8

Supongamos que tengo la siguiente macro:cómo redefinir una macro utilizando su definición anterior

#define xxx(x) printf("%s\n",x); 

Ahora bien, en ciertos archivos que desea utilizar una "mejorada" versión de este macro sin cambiar su nombre. La nueva versión explora la funcionalidad de la versión original y hace algo más de trabajo.

#define xxx(x) do { xxx(x); yyy(x); } while(0) 

Por supuesto, esto me da la advertencia redefition pero ¿por qué recibo el mensaje 'xxx' no fue declarado en este ámbito? ¿Cómo debería definirlo correctamente?

EDIT: de acuerdo con este http://gcc.gnu.org/onlinedocs/gcc-3.3.6/cpp/Self_002dReferential-Macros.html debería ser posible

+1

Esa página macros autorreferenciales está describiendo las reglas evitando la recursión infinita de la sustitución de macro. No significa que pueda definir una macro para que signifique más de una cosa. –

Respuesta

0

No es exactamente lo que estás pidiendo, pero puede ayudar.

Puede #undef una macro antes de darle una nueva definición.

Ejemplo:

#ifdef xxx 
#undef xxx 
#endif 
#define xxx(x) whatever 

Nunca oí de (o visto) una macro recursiva sin embargo. No creo que sea posible.

+2

Tenga en cuenta que el bloque '# ifdef' no es necesario. Puede usar '# undef' en un nombre para definirlo como una macro, incluso si ese nombre no está definido actualmente como una macro. Entonces, puedes simplemente '#undef xxx' y luego' #define xxx ... '. –

+0

@James McNellis: es bueno saberlo. ¡Gracias! – ereOn

6

No es posible. Las macros pueden usar otras macros pero están usando la definición disponible en el tiempo de expansión, no en el tiempo de definición. Y las macros en C y C++ no pueden ser recursivas, por lo que xxx en su nueva macro no se expande y se considera como una función.

3

No podrá reutilizar la definición anterior de la macro, pero puede definirla indefinidamente y hacer la nueva definición. Con suerte, no es demasiado complicado copiar y pegar.

#ifdef xxx 
#undef xxx 
#endif 
#define xxx(x) printf("%s\n",x); 

Mi recomendación es definir una macro xxx2.

#define xxx2(x) do { xxx(x); yyy(x); } while(0); 
+3

Tenga en cuenta que el bloque '# ifdef' no es necesario. Puede usar '# undef' en un nombre para definirlo como una macro, incluso si ese nombre no está definido actualmente como una macro. Entonces, puedes simplemente '#undef xxx' y luego' #define xxx ... '. –

+0

¡Genial! No sabia sobre eso. Dejar el '# ifdef' hace que el código sea más legible. – Mike

+0

Tengo un Project-Prefix.pch donde establezco los valores predeterminados que son comunes para la aplicación de mis aplicaciones y luego tengo Prefix.pch específico de la aplicación para las cosas que cambian. Obtuve una advertencia 'Macro de problema de léxico o preprocesador redefinida' cuando redefiní una macro y no pude encontrar la manera de desactivar esa advertencia en el preprocesador. #undef PLAY_BUTTON_TITLE y luego #define PLAY_BUTTON_TITLE @ "Start" suprime el error y redefine el botón. – JScarry

2

Si conocemos el tipo de parámetro 'x' en la macro 'xxx', podemos redefinir macro utilizándolo en una función y luego definir la macro 'xxx' como esta función

definición original de la macro 'xxx':

#define xxx(x) printf("xxx %s\n",x); 

En una versión determinada marca archivo mejorada del 'xxx' macro:

/* before redefining the "xxx" macro use it in function 
* that will have enhanced version for "xxx" 
*/ 
static inline void __body_xxx(const char *x) 
{ 
    xxx(x); 
    printf("enhanced version\n"); 
} 

#undef xxx 
#define xxx(x) __body_xxx(x) 
Cuestiones relacionadas