2011-11-27 20 views
15

Cuando utilizo este código:¿Cuál es la diferencia entre las macros "#define STR (x) #x" y "#define STR (x) VAL (x)" con "#define VAL (x) #x"?

#include <stdio.h> 
#define STR(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

imprime

hello.c__LINE__hello! 

pero cuando se utiliza esto:

#include <stdio.h> 
#define STR(x) VAL(x) 
#define VAL(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

imprime

hello.c7hello! 

lo que es la diferencia entre

#define STR(x) #x 

y

#define STR(x) VAL(x) 
#define VAL(x) #x 
+0

¿Qué sucede si define VAL (X) primero? ¿Obtienes los mismos resultados? – I82Much

+0

sí, lo mismo con definir STR (x) primero – vv1133

+0

posible duplicado de [¿Cuál es el paso exacto de la macro expansión?] (Http://stackoverflow.com/questions/6742501/whats-the-exact-step-of-macro -expandiendo) – codaddict

Respuesta

9

argumentos a las macros son en sí mismos-macro expandida, excepto donde el nombre de argumento macro aparece en el cuerpo de la macro con la stringifier # o el token-parche ##.

En el primer caso, el argumento de STR es no macro expandido, por lo que acaba de obtener el nombre de la macro LINE.

En el segundo caso, el argumento de STR es macro expandido cuando se lo sustituye en la definición de VAL, por lo que funciona: se obtiene el número de línea real porque la macro LINE se expande.

0

C99 N1256 standard draft 6.10.3.1/1 "sustitución argumento":

Después de los argumentos a favor de la invocación de una macro-función como han sido identificados, sustitución argumento lleva a cabo. Un parámetro en la lista de reemplazo, a menos que haya precedido con un token de preprocesamiento # o ## o seguido de un token de preprocesamiento ## (ver a continuación), es reemplazado por el argumento correspondiente después de que todas las macros contenidas en él hayan sido expandidas. Antes de ser sustituidos, los tokens de preprocesamiento de cada argumento son completamente macro reemplazados como si formaran el resto del archivo de preprocesamiento; no hay otros tokens de preprocesamiento disponibles.

Así # y ## dé argumentos ser tratados de manera diferente.

Cuestiones relacionadas