Pregunta

Estoy tratando de averiguar qué versión de Aumentar mi código piensa que está utilizando.Quiero hacer algo como esto:

#error BOOST_VERSION

pero el preprocesador no se expande BOOST_VERSION.

Sé que podría imprimir en tiempo de ejecución del programa, y sé que yo podría mirar la salida del preprocesador para encontrar la respuesta.Siento como si hubiera una manera de hacer esto durante la compilación podría ser útil.

¿Fue útil?

Solución

Si está utilizando Visual C ++, puede utilizar #pragma message:

#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))

Editar Gracias a LB para el enlace

Al parecer, la GCC es equivalente (no probado):

#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)

Otros consejos

BOOST_PP_STRINGIZE parece una excelente solución para C ++, pero no para C regular.

Aquí está mi solución para GNU CPP:

/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"

/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "="  VALUE(var)

/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))

Por encima de las definiciones resultan en:

test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"

"definido como número entero" , "se define como una cadena" y "definido, pero ningún valor" las variables, que funciona muy bien . Sólo para "no definido" variables, que muestra exactamente el mismo que el nombre variable original. Usted tiene que acostumbrarse a él -. O tal vez alguien puede proporcionar una mejor solución

Sé que esto es mucho tiempo después de la consulta original, pero esto puede resultar útil.

Esto se puede hacer en GCC usando el operador stringify "#", pero requiere dos etapas.

#define XSTR(x) STR(x)
#define STR(x) #x

El valor de una macro a continuación, se puede visualizar con:

#pragma message "The value of ABC: " XSTR(ABC)

Vea:. 3.4 Stringification en la documentación en línea gcc

¿Cómo funciona?:

El preprocesador entiende cadenas entre comillas y los maneja de manera diferente del texto normal. La concatenación de cadenas es un ejemplo de este tratamiento especial. El pragma mensaje requiere un argumento que es una cadena entre comillas. Cuando hay más de un componente al argumento entonces todos ellos deben ser cadenas de manera que la concatenación de cadenas se puede aplicar. El preprocesador nunca puede asumir que una cadena sin comillas debe ser tratado como si fuera citado. Si lo hizo entonces:

#define ABC 123
int n = ABC;

No se compilará.

Ahora considere:

#define ABC abc
#pragma message "The value of ABC is: " ABC

que es equivalente a

#pragma message "The value of ABC is: " abc

Esto provoca una advertencia preprocesador porque abc (sin comillas) no se puede concatenar con la cadena anterior.

Ahora considere el stringize preprocesador (que una vez fue llamado stringification, los eslabones de la documentación se han cambiado para reflejar la terminología revisada. (Ambos términos, dicho sea de paso, son igualmente detestable. El término correcto es, por supuesto, stringifaction. Sea listo para actualizar sus enlaces.)) operador. Esto actúa sólo en los argumentos de una macro y sustituye el argumento no expandido con el argumento entre comillas dobles. Así:

#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);

asignará valores idénticos a s1 y s2. Si ejecuta gcc -E se puede ver esto en la salida. Tal vez STR se llamaría algo así como una mejor ENQUOTE.

Esto resuelve el problema de poner comillas alrededor de un elemento no indicada, el problema ahora es que, si el argumento es una macro, la macro no se ampliará. Esto es por qué es necesaria la segunda macro. XSTR amplía su argumento, entonces llama a STR para poner el valor expandido entre comillas.

Por lo que yo sé '# error' sólo se imprimirá cuerdas, de hecho que Don Ni siquiera necesidad de usar comillas .

¿Usted ha intentado escribir Otros código incorrecto a propósito el uso de "BOOST_VERSION"? Tal vez algo así como "bla [BOOST_VERSION] = foo"; le dirá algo así como "cadena 1.2.1 literal no puede ser utilizado como una dirección de matriz". No será un mensaje de error bastante, pero al menos él se puede mostrar el valor correspondiente. Se puede jugar hasta que encuentre un error de compilación que no le dirá el valor.

Sin impulso:

  1. definir misma de nuevo macro y el compilador mismo será dar la advertencia.

  2. A partir de advertencia se puede ver la ubicación de la definición anterior.

  3. archivo vi de la definición anterior.

ambarish@axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition

#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666

int main ()
{

}
#define a <::BOOST_VERSION>
#include a
MSVC2015 : error grave C1083: No se puede abrir archivo de inclusión: ':: 106200': No existe el fichero o directorio

Funciona incluso si está activada la preprocess to file, incluso si los tokens no válidos están presentes:

#define a <::'*/`#>
#include a
MSVC2015 : error grave C1083: No se puede abrir archivo de inclusión: '::' * / '#': No existe el fichero o directorio
GCC4.x : aviso: falta de terminación 'carácter [-Winvalid-pp-token]
    #define un <:: '* /' #>

En Microsoft C / C ++, puede utilizar las constantes integradas _CRT_STRINGIZE() imprimir. Muchos de mis archivos stdafx.h contienen alguna combinación de estos:

#pragma message("_MSC_VER      is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER      is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER      is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER        is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT  is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE     is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION)) 

y da salida a algo como esto:

_MSC_VER      is 1915
_MFC_VER      is 0x0E00
_ATL_VER      is 0x0E00
WINVER        is 0x0600
_WIN32_WINNT  is 0x0600
_WIN32_IE     is 0x0700
NTDDI_VERSION is 0x06000000

También puede procesar previamente el archivo de origen y ver lo que el valor se evalúa como preprocesador.

¿Está buscando

#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif

No es grande si BOOST_VERSION es una cadena, como he asumido, pero también puede ser enteros individuales definidas para los números mayores, menores y revisión.

En cuanto a la salida del preprocesador es lo más parecido a la respuesta que pide.

Sé que ha excluido que (y otras formas), pero no estoy seguro de por qué. Usted tiene un problema lo suficientemente específico para resolver, pero no ha explicado por qué cualquiera de los métodos "normales" no funcionan bien para usted.

Se puede escribir un programa que imprime BOOST_VERSION y compilar y ejecutarlo como parte de su sistema de construcción. De lo contrario, creo que estás fuera de suerte.

BOOST_VERSION se define en el archivo de cabecera version.hpp impulso.

Tome un vistazo a la documentación Boost, así, en cuanto a cómo se está utilizando la macro:

En referencia a BOOST_VERSION, desde 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 :

  

Describe el número de versión impulso en   xxyyzz formato tal que:    (BOOST_VERSION % 100) es la sub-menor   versión, ((BOOST_VERSION / 100) %    1000) es la versión menor, y    (BOOST_VERSION / 100000) es la mayor   versión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top