2009-12-23 22 views
7

tengo el siguiente códigoMacro y la función con el mismo nombre

#define myfunc(a,b) myfunc(do_a(a), do_b(b)) 

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 

Quiero que el pre-procesador para ampliar myfunc función sólo al llamar. código necesario después del pre-procesamiento se ve así:

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
int main() 
{ 
    int x = 6, y = 7; 
    myfunc(do_a(x),do_b(y)); 

    return 0; 
} 

El problema se se expande también que la definición de una función como esta

void myfunc(do_a(int a), do_b(int b)) 
{ 
    do_blah(a,b); 
} 

¿Hay alguna manera de hacer macro se expande sólo si estamos ampliando una función ¿llamada? He intentado muchas soluciones, y parece imposible, pero espero que alguien vio situación como esta ..

NOTA: Por favor, no me diga que cambiar el nombre de los nombres de macro o función: D

Update1: Gracias por tu ayuda. Pero solo puedo cambiar la definición de la macro, no puedo cambiar su posición y no puedo cambiar la implementación de la función.

Respuesta

15

Uso () para detener el preprocesador de la ampliación de la definición de función:

#include <stdio.h> 

#define myfunc(a, b) myfunc(do_a(a), do_b(b)) 
/* if you have a preprocessor that may be non-standard 
* and enter a loop for the previous definition, define 
* myfunc with an extra set of parenthesis: 
#define myfunc(a, b) (myfunc)(do_a(a), do_b(b)) 
******** */ 

int (myfunc)(int a, int b) /* myfunc does not get expanded here */ 
{ 
    printf("a=%d; b=%d\n", a, b); 
    return 0; 
} 

int do_a(int a) 
{ 
    return a * 2; 
} 

int do_b(int b) 
{ 
    return b - 5; 
} 

int main(void) 
{ 
    myfunc(4, 0); 
    return 0; 
} 
+0

Funciona :) gracias – Yousf

+0

Creo que algunos preprocesadores pueden obstaculizar el uso recursivo de la forma myfunc (xxx, xxx).Lo haría myfunC#define (a, b) (myfunc) (do_a (a), do_b (b)) int (myfunc) (int a, int b) etc. –

+2

Buen punto, Tim, gracias ! Pero creo que es seguro suponer que el preprocesador nunca ingresará un bucle recursivo (cf Estándar 6.10.3.4/2 "... si alguno de los reemplazos anidados encuentra el nombre de la macro que se reemplaza, no se reemplaza ..."). – pmg

0

Defina la macro después de definir la función.

Alternativamente, utilizar un patrón como este:

#define myfunc_macro(a,b) myfunc(do_a(a), do_b(b)) 
#define myfunc(a,b) myfunc_macro(a,b) 

. 
. 

#undef myfunc 
void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
#define myfunc(a,b) myfunc_macro(a,b) 

. 
. 

int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 
3

Definir el macro después de la Defintion de la función.

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 

#define myfunc(a,b) myfunc(do_a(a), do_b(b)) 

int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 
8

veo tres posibles soluciones:

  • definen la macro después de definición de la función.

  • definir, antes de la definición de la función, do_a() y do_b() tal que devuelven su argumento, y redefinir ellos a su voluntad después de la definición de la función

  • realizar do_a() y do_b() dentro de la función:

    void myfunc(int a, int b) 
    { 
        do_blah(do_a(a),do_b(b)); 
    } 
    

Tengo una fuerte preferencia por este último.

0

¿Por qué no puede cambiar el código fuente? En el peor de los casos, si necesita mantener la versión original, ejecute patch en ella para crear un archivo temporal en el que se renombre la función y compilarla desde allí.

+0

es el código heredado .. función de cambio o los nombres de macro no es una opción. – Yousf

+0

Es simplemente imposible que pueda cambiar la macro y no la función. Es simplemente imposible que pueda compilar un archivo pero no elegir qué archivo compilar. Estás hablando basura. –

Cuestiones relacionadas