Operador de conversión a cadenas (#)
El operador de signo de número o de "generación de cadenas" (#) convierte parámetros de macro en literales de cadena sin expandir la definición del parámetro. Se utiliza únicamente con las macros que toman argumentos. Si precede un parámetro formal en la definición de macro, el argumento real pasado por la llamada de macro se pone entre comillas y se trata como un literal de cadena. El literal de cadena reemplaza cada aparición de una combinación de operador de generación de cadenas y parámetro formal dentro de la definición de macro.
Nota:
Ya no se admite la extensión de Microsoft C (versión 6.0 y anteriores) para el estándar ANSI C que expandía los argumentos formales de macro que aparecían dentro de literales de cadena y constantes de caracteres. El código que dependía de esta extensión se debe volver a escribir mediante el operador de generación de cadenas (#).
Se ignora el espacio en blanco que precede al primer token y sigue al último token del argumento real. Cualquier espacio en blanco entre los tokens del argumento real se reduce a un único espacio en blanco en el literal de cadena resultante. Así, si se incluye un comentario entre dos tokens en el argumento real, se reduce a un único espacio en blanco. El literal de cadena resultante se concatena automáticamente con cualquier literal de cadena adyacente que está separada solo por espacio en blanco.
Además, si un carácter contenido en el argumento normalmente requiere una secuencia de escape cuando se utiliza en un literal de cadena (por ejemplo, las comillas dobles ("
) o la barra diagonal inversa (\
), se insertará automáticamente la secuencia de escape de barra diagonal inversa antes del carácter.
El operador de generación de cadenas de Microsoft C++ no se comporta correctamente cuando se usa con cadenas que incluyen secuencias de escape. En esta situación, el compilador generará un Error del compilador C2017.
Ejemplos
En el ejemplo siguiente se muestra una definición de macro que incluye el operador de generación de cadenas y una función principal que invoca la macro:
// stringizer.cpp
#include <stdio.h>
#define stringer( x ) printf_s( #x "\n" )
int main() {
stringer( In quotes in the printf function call );
stringer( "In quotes when printed to the screen" );
stringer( "This: \" prints an escaped double quote" );
}
Las macros stringer
se expanden durante el preprocesamiento, lo que genera el código siguiente:
int main() {
printf_s( "In quotes in the printf function call" "\n" );
printf_s( "\"In quotes when printed to the screen\"" "\n" );
printf_s( "\"This: \\\" prints an escaped double quote\"" "\n" );
}
In quotes in the printf function call
"In quotes when printed to the screen"
"This: \" prints an escaped double quote"
En el ejemplo siguiente se muestra cómo se puede expandir un parámetro de macro:
// stringizer_2.cpp
// compile with: /E
#define F abc
#define B def
#define FB(arg) #arg
#define FB1(arg) FB(arg)
FB(F B)
FB1(F B)