2009-05-13 13 views
6

Me gustaría obtener el preprocesador C para generar macros para mí (es decir, estoy usando solo C99). Me gustaría escribir una macro¿Macros de macroproducción en C?

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

y cuando pongo

make_macro(name1) 
make_macro(name2) 

adelante en el código, que se expandiría para

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

y yo entonces sería capaz de utilizar nombre1 y name2 como funciones (macro implementadas). Creo que estoy atascado usando macros en ambos pasos: tiene sentido usar una macro para volver a llenar repetidamente una plantilla, y el manejo vario de argumentos no funcionará excepto a través de una macro.

Así que lo que entra en el < ... magia aquí ...> marcador de posición para hacer esto? En este punto, estoy empezando a creer que no es posible en C99, pero tal vez me faltan algunos detalles de sintaxis.

+0

¿por qué una macro? No entiendo este punto de "repetidamente volver a llenar una plantilla". ¿Qué plantilla y qué recarga? –

Respuesta

5

No es posible en C estándar

1

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

uso como esto:

make_macro(name1) 
make_macro(name2,1) 

y esto generaría

name1_fn(name1_info) 
name2_fn(name2_info,1) 
3

No es posible debido a que la macro se realiza sólo una vez.

Esto no quiere decir que no se podía utilizar otras macros en su macro, pero no se podía hacer

#define TEST #define HALLO 33 

int x = TEST; 

y esperar que x sea 33 después! lo que se obtendría un error de sintaxis porque intentó

int x = #define HALLO 33; 

O tal vez el compilador ya se queja de # define en #define.

3

¿Ha considerado utilizar macros M4? Creo que están disponibles en la mayoría de las plataformas, por lo que no debería ser una limitación.

M4 GNU page

+1

+1, M4 a menudo se pasa por alto y es una herramienta de generación de código muy poderosa. Sin embargo, desearía que la gente dejara de hacer bromas con LISP cada vez que me vieran usarlo. –

1

Como todo el mundo ha dicho, no se puede hacer exactamente lo que está pidiendo.

Usted puede ser capaz de hacer algo así forzando el preprocesor C para funcionar en dos ocasiones, por ejemplo, con una regla de este tipo en el makefile:

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

A continuación, dar el archivo de la extensión de test.pp . Makefile lo ejecutará una vez para generar el archivo .c y luego la ejecución normal en el archivo .c se ejecutará una segunda vez.

Personalmente, prefiero escribir un script externo en Perl o algo para generar el código C para mí; es un poco más limpio que jugar juegos con el preprocesador C. Depende de la cantidad de código de la que estamos hablando.

+0

inteligente, pero tengo la sensación de que ejecutar CPP en la salida de CPP podría causar problemas con líneas como pragmas y números de línea. – Michael

1

Según C99 Section 6.10.3.2:

Cada # preprocesamiento token en la lista de reemplazo para una macro-función como se seguido por un parámetro como el siguiente token de procesamiento previo en la lista de reemplazo.

Por lo tanto, ciertamente se podría poner un #define en una macro si tiene un parámetro denominado define pero nunca va a hacer lo que desea. Esto a menudo me molesta ya que tengo que trabajar en C y, como tal, no puedo usar plantillas de C++.