2009-12-23 27 views
7

Ho il seguente codiceMacro e funzione con lo stesso nome

#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; 
} 

voglio il pre-processore per espandere function funzione solo in caso di chiamata. codice richiesto dopo il pre-processing si presenta così:

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; 
} 

Il problema è che la definizione di funzione è espansa anche in questo modo

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

C'è un modo per rendere la macro si espande solo se stiamo espandendo una funzione chiamata? Ho provato molte soluzioni, e sembra impossibile, ma spero che qualcuno ha visto situazione come questa ..

NOTA: per favore non mi dica per rinominare i nomi delle macro o funzione: D

Update1: Grazie per il tuo aiuto. Ma posso solo cambiare la definizione della macro, non posso cambiare la sua posizione e non posso cambiare l'implementazione della funzione.

risposta

15

Usa () per fermare il preprocessore di espandere la definizione di funzione:

#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

Funziona :) grazie – Yousf

+0

Penso che alcuni preprocessori potrebbero rifiutare l'uso ricorsivo del modulo myfunc (xxx, xxx).Farei #define myfunc (a, b) (myfunc) (do_a (a), do_b (b)) int (myfunc) (int a, int b) ec & –

+2

Buon punto, Tim, grazie ! Ma penso che sia sicuro supporre che il preprocessore non inserirà mai un ciclo ricorsivo (cfr. Standard 6.10.3.4/2 "... se qualche sostituzione annidata incontra il nome della macro che viene sostituita, non viene sostituita ..."). – pmg

0

Definire la macro dopo aver definito la funzione.

alternativa, utilizzare un modello come questo:

#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

Definire la macro dopo alla definizione di funzione.

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

Vedo tre possibili soluzioni:

  • definiscono la macro dopo la definizione della funzione.

  • definire, prima della definizione della funzione, do_a() e do_b() tale che essi restituiscono la loro tesi, e ridefinire a vostro piacimento dopo definizione della funzione

  • eseguire do_a() e do_b() all'interno della funzione:

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

Ho una forte preferenza per quest'ultimo.

0

Perché non è possibile modificare il codice sorgente? Nel peggiore dei casi, se è necessario mantenere la versione originale, eseguire un patch su di esso per creare un file temporaneo in cui la funzione viene rinominata e costruirla da lì.

+0

è il codice legacy .. funzione di cambiare o nomi di macro non è un'opzione. – Yousf

+0

È semplicemente impossibile modificare la macro e non la funzione. È semplicemente impossibile compilare un file ma non scegliere quale file compilare. Stai parlando di spazzatura. –

Problemi correlati