2009-05-13 29 views
6

Mi piacerebbe ottenere il preprocessore C per generare macro (ad esempio, sto utilizzando solo C99). Mi piacerebbe scrivere una macroMacro di produzione di macro in C?

#define make_macro(in) <...magic here...> 

e quando ho messo

make_macro(name1) 
make_macro(name2) 

avanti nel codice, si espanderebbe a

#define name1(...) name1_fn(name1_info, __VA_ARGS__) 
#define name2(...) name2_fn(name2_info, __VA_ARGS__) 

e sarei quindi in grado di utilizzare nome1 e name2 come funzioni (implementate macro). Penso di essere bloccato usando le macro in entrambi i passaggi: ha senso usare una macro per riempire ripetutamente un modello, e la gestione degli argomenti variadici non funzionerà se non tramite una macro.

Quindi cosa va nella < ... magia qui ...> segnaposto per fare questo? A questo punto, sto iniziando a credere che non sia possibile in C99, ma forse mi mancano alcuni dettagli di sintassi.

+0

perché una macro? non ottengo questo punto "per riempire ripetutamente un modello". quale modello e quale ricarica? –

risposta

5

Non è possibile in serie C.

1

Prova #define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__).

Usa come questo:

make_macro(name1) 
make_macro(name2,1) 

e questo genererebbe

name1_fn(name1_info) 
name2_fn(name2_info,1) 
3

Non è possibile perché la macro viene eseguita una sola volta.

Questo non significa che non è possibile utilizzare altre macro nella macro, ma non si poteva fare

#define TEST #define HALLO 33 

int x = TEST; 

e si aspettano di essere x 33 dopo! quello che si otterrebbe un errore di sintassi perché si è tentato

int x = #define HALLO 33; 

O forse il compilatore si lamenta già circa #define in #define.

3

Hai considerato l'utilizzo di macro M4? Penso che siano disponibili sulla maggior parte delle piattaforme, quindi non dovrebbe essere una limitazione.

M4 GNU page

+1

+1, M4 è spesso trascurato ed è uno strumento di generazione del codice molto potente. Vorrei che la gente si fermasse con le battute del LISP ogni volta che mi vedessero ad usarlo, comunque. –

1

Come tutti hanno detto, non si può fare esattamente quello che stai chiedendo.

Potreste essere in grado di fare una cosa del genere forzando la preprocesor C per eseguire due volte, ad esempio, con una regola come questa nel makefile:

.c.pp: 
    $(CPP) $< -o [email protected] 

Poi dare il file l'estensione del test.pp . Il Makefile lo eseguirà una volta per generare il file .c, quindi la normale esecuzione sul file .c lo eseguirà una seconda volta.

Personalmente, preferisco scrivere uno script esterno in Perl o qualcosa per generare il codice C per me; è un po 'più pulito rispetto ai giochi con il pre-processore C. Dipende da quanto codice stiamo parlando.

+0

intelligente, ma ho la sensazione che l'esecuzione di CPP sull'output di CPP potrebbe causare problemi con linee come un pragma e numeri di riga. – Michael

1

Secondo C99 Section 6.10.3.2:

Ogni # pre-elaborazione di token nella lista sostituzione di una funzione macro-come sono seguito da un parametro come il token successivo pre-elaborazione della lista di sostituzione.

Quindi, si potrebbe certamente mettere un #define in una macro se si dispone di un parametro denominato define ma non potrà mai fare ciò che desideri. Questo spesso mi infastidisce dal momento che devo lavorare in C e in quanto tale non posso usare i template C++.