Estoy tratando de averiguar qué versión de Boost cree que está usando mi código. Quiero hacer algo como esto:
#error BOOST_VERSION
pero el preprocesador no expande BOOST_VERSION.
Sé que podría imprimirlo en tiempo de ejecución desde el programa y sé que podría mirar la salida del preprocesador para encontrar la respuesta. Siento que tener una forma de hacer esto durante la compilación podría ser útil.
macros
c-preprocessor
boost-preprocessor
Jim Hunziker
fuente
fuente
Respuestas:
Sé que esto es mucho después de la consulta original, pero aún puede ser útil.
Esto se puede hacer en GCC usando el operador de cadena "#", pero requiere dos etapas.
El valor de una macro se puede mostrar con:
Consulte: 3.4 Cadena de caracteres en la documentación en línea de gcc.
Cómo funciona:
El preprocesador entiende las cadenas entre comillas y las maneja de manera diferente al texto normal. La concatenación de cadenas es un ejemplo de este tratamiento especial. El pragma del mensaje requiere un argumento que sea una cadena entre comillas. Cuando hay más de un componente en el argumento, todos deben ser cadenas para que se pueda aplicar la concatenación de cadenas. El preprocesador nunca puede asumir que una cadena sin comillas debe tratarse como si estuviera entre comillas. Si lo hizo, entonces:
no compilaría.
Ahora considere:
que es equivalente a
Esto provoca una advertencia del preprocesador porque abc (sin comillas) no se puede concatenar con la cadena anterior.
Ahora considere el preprocesador stringize (que una vez se llamó stringificación, los enlaces en la documentación se han cambiado para reflejar la terminología revisada. (Ambos términos, por cierto, son igualmente detestables. El término correcto es, por supuesto, stringifaction. Esté listo para actualizar sus enlaces.)) operador. Esto actúa solo sobre los argumentos de una macro y reemplaza el argumento no expandido con el argumento entre comillas dobles. Así:
asignará valores idénticos a s1 y s2. Si ejecuta gcc -E, puede ver esto en la salida. Quizás STR se llamaría mejor algo como ENQUOTE.
Esto resuelve el problema de poner comillas alrededor de un elemento sin comillas, el problema ahora es que, si el argumento es una macro, la macro no se expandirá. Por eso se necesita la segunda macro. XSTR expande su argumento, luego llama a STR para poner el valor expandido entre comillas.
fuente
__IPHONE_9_3
.BOOST_PP_STRINGIZE
parece una excelente solución para C ++, pero no para C.Aquí está mi solución para GNU CPP:
Las definiciones anteriores dan como resultado:
Para las variables "definido como entero" , "definido como cadena" y "definido pero sin valor" , funcionan bien. Solo para la variable "no definida" , se muestran exactamente igual que el nombre de la variable original. Tienes que acostumbrarte, o tal vez alguien pueda proporcionar una mejor solución.
fuente
DEFINED_INT=(sizeof(MY_STRUCT))
, sinsizeof
que se evalúe al operador.sizeof
., Sin embargo, deja de ser curioso si hay una forma inteligente de conseguir esto)#define masks {0xff, 0xaf, 0x0f}
Si está utilizando Visual C ++, puede utilizar
#pragma message
:Editar: Gracias a LB por el enlace
Aparentemente, el equivalente de GCC es (no probado):
fuente
BOOST_PP_STRINGIZE
cuál es agradable y breve y se puede copiar / pegar.Hasta donde yo sé, '#error' solo imprimirá cadenas, de hecho , ni siquiera necesita usar comillas .
¿Ha intentado escribir varios códigos incorrectos a propósito con "BOOST_VERSION"? Quizás algo como "blah [BOOST_VERSION] = foo;" le dirá algo como "el literal de cadena 1.2.1 no se puede utilizar como una dirección de matriz". No será un mensaje de error bonito, pero al menos te mostrará el valor relevante. Puede jugar hasta que encuentre un error de compilación que le indique el valor.
fuente
std::vector<BOOST_VERSION>;
en gcc 4.4.1. ¡Gracias!Sin impulso:
defina la misma macro nuevamente y el compilador HIMSELF le dará una advertencia.
Desde la advertencia puede ver la ubicación de la definición anterior.
Archivo vi de definición anterior.
fuente
__cplusplus
.En Microsoft C / C ++, puede utilizar el integrado
_CRT_STRINGIZE()
para imprimir constantes. Muchos de misstdafx.h
archivos contienen alguna combinación de estos:y genera algo como esto:
fuente
Funciona incluso si
preprocess to file
está habilitado, incluso si hay tokens no válidos:fuente
Build error: #include expects "FILENAME" or <FILENAME>
. Suspiro.'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
También puede preprocesar el archivo fuente y ver a qué se evalúa el valor del preprocesador.
fuente
Estás buscando
No es genial si BOOST_VERSION es una cadena, como he asumido, pero también puede haber enteros individuales definidos para los números mayor, menor y de revisión.
fuente
#if VARIABLE == 123
declaración sobre la marcha y el resaltado de sintaxis me dice si es el valor que creo que es o no ...Mirar la salida del preprocesador es lo más parecido a la respuesta que pide.
Sé que ha excluido eso (y otras formas), pero no estoy seguro de por qué. Tiene un problema suficientemente específico que resolver, pero no ha explicado por qué ninguno de los métodos "normales" no le funciona bien.
fuente
Puede escribir un programa que imprima,
BOOST_VERSION
compile y ejecute como parte de su sistema de compilación. De lo contrario, creo que no tienes suerte.fuente
BOOST_VERSION se define en el archivo de encabezado de boost version.hpp.
fuente
Eche un vistazo también a la documentación de Boost, con respecto a cómo está usando la macro:
En referencia a
BOOST_VERSION
, de http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros :fuente
En lugar de #error, intente redefinir la macro, justo antes de que se utilice. La compilación fallará y el compilador proporcionará el valor actual que cree que se aplica a la macro.
#define BOOST_VERSION bla
fuente