2010-08-20 8 views
13

Estoy leyendo el código fuente del phoneME. Es una implementación de FOSS JavaME. Está escrito en C++ y me encontré con este:¿Qué hace "#define STR (a) #a"?

// Makes a string of the argument (which is not macro-expanded) 
#define STR(a) #a 

sé C y C++, pero nunca he leído algo como esto. ¿Qué hace el # en #a?

También, en el mismo archivo, hay:

// Makes a string of the macro expansion of a 
#define XSTR(a) STR(a) 

Es decir, ¿cuál es el uso de la definición de una nueva macro, si todo lo que hace es llamar a una macro existente?

El código fuente está en https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. Puedes encontrarlo con CTRL + F.

+0

Aparentemente esto (específicamente la combinación de las macros 'STR' y' XSTR') se llama el "truco de doble stringize". Hay una muy buena explicación en la pregunta [¿Cómo funciona exactamente el truco de doble cadena?] (http://stackoverflow.com/questions/2751870/how-exactly-does-the-double-stringize-trick-work) – sleske

Respuesta

19

En la primera definición, #a significa imprimir el argumento macro como una cadena. Esto cambiará, p. STR(foo) en "foo", pero no hará macroexpansión en sus argumentos.

La segunda definición no agrega nada al primero, pero al pasar su argumento a otra macro, fuerza la expansión completa de macros de su argumento. Así que XSTR(expr) crea una cadena de expr con todas las macros completamente expandidas.

+0

+1, me gusta después de leer varios –

5

# es el operador de torceado. El preprocesador crea una cadena fuera del parámetro.

Digamos que tienes:

STR(MyClass); 

Sería procesados ​​previamente como:

"MyClass"; 

El nivel de indirección (usando XSTR()) tiene que ver con las reglas de expansión de macro.

4

El #a se conoce como stringizer operator. Toma el parámetro formal, en este caso a, y lo convierte en una cadena encerrándolo entre comillas dobles.

Así que si usted tiene:

string s = STR("my quoted string"); 
cout << s; 

La salida sería:

"my quoted string" 
+5

No es que importe, pero creo que "stringizer" es solo de Microsoft; normalmente es el operador "stringify" y el proceso se llama "stringification" –

+0

Thx para la corrección. :) –

+2

Si vas a inventar palabras, entonces "stringify" y "stringise" son tan cromáticas como las demás. Propongo "stringulate". –

4

En primer lugar, debe saber que este par de macros es realmente bastante común. El primero hace exactamente lo que dice el comentario: convierte un argumento en una cadena encerrándolo entre comillas dobles.

El segundo se utiliza para causar macro expansión del argumento. Por lo general, los usa junto algo como esto:

#define a value_a 

printf("%s", XSTR(a)); 

La expansión de la macro se expandirá a a string_a y el stringify a su vez, que en una cadena, por lo que la salida será value_a.

Cuestiones relacionadas