2010-09-22 15 views
6

Después de leer sobre VA_NARGpegar simbólico en C

me trató de poner en práctica la sobrecarga de funciones dependiendo del número de argumentos en C el uso de macros. Ahora el problema es:

void hello1(char *s) { ... } 
void hello2(char *s, char *t) { ... } 
// PP_NARG(...)   macro returns number of arguments :ref to link above 
// does not work 
#define hello(...)   hello ## PP_NARG(__VA_ARGS__) 

int main(void) 
{ 
    hello("hi"); // call hello1("hi"); 
    hello("foo","bar"); // call hello2("foo","bar"); 
    return 0; 
} 

He leído this de C-FAQ. Pero todavía no podía conseguir que funcione ...

Respuesta

4

Esto es debido a las reglas de evaluación para las macros. Tendría que definir algún tipo de macro auxiliar que recibe el número como token:

#define HELLO_1(N, ...)   hello ## N 
#define HELLO_0(N, ...)   HELLO_1(N, __VARGS__) 
#define HELLO(...)   HELLO_0(PP_NARG(__VA_ARGS__), __VARGS__) 

o menos. También puede echar un vistazo a la presentación de la documentación de P99. Esto le proporcionará macro herramientas más cómodas para hacerlo directamente.

+0

"más o menos" de hecho. Se necesita un nivel más de indirección para que funcione. –

+0

@John: sí, gracias. Siempre uso mi propia versión de macro de pegado para eso, así que me es difícil recordar cuántos niveles de direccionamiento indirecto necesitas si solo tienes '##'. Adapte mi respuesta en consecuencia. –

+0

Gracias que funciona. pero HOLA ("foo") da hello1; no hello1 ("foo"). Pero tengo la idea ... – Nyan

0

que no tienen un compilador C99 disponibles para comprobar, pero esto debería funcionar:

#define helloN(N, ...) hello ## N (__VA_ARGS__) 
#define hello(...) helloN(PP_NARG(__VA_ARGS__), __VA_ARGS__) 
4

¡Esa PP_NARG es una locura bastante impresionante!

Siguiendo el ejemplo glue en el estándar C99 (6.10.3.5, ejemplo 4), la siguiente produce los resultados deseados:

#define glue(a, b) a ## b 
#define xglue(a, b) glue(a, b) 

#define hello(...) xglue(hello, PP_NARG(__VA_ARGS__))(__VA_ARGS__)