sintaxis programación programacion para ingenieros ejemplos dev comandos codigos basicos c++ boost macros c-preprocessor

programacion - programación en c++ para ingenieros



¿Puedo redefinir una macro de C++ y luego definirla de nuevo? (3)

Estoy usando tanto la Biblioteca JUCE como varios encabezados de Boost en mi código. Juce define "T" como una macro (gemido), y Boost a menudo usa "T" en sus definiciones de plantilla. El resultado es que si de alguna manera incluye los encabezados JUCE antes de los encabezados de Boost, el preprocesador expande la macro JUCE en el código de Boost, y luego el compilador se pierde irremediablemente.

Mantener mis archivos en el orden correcto no es difícil la mayor parte del tiempo, pero puede ser complicado cuando tienes una clase JUCE que incluye algunas otras clases y en algún lugar de la cadena un archivo incluye Boost, y si alguno de los archivos anteriores necesitaba un JUCE, incluye que estás en problemas.

Mi esperanza inicial de arreglar esto era

#undef T

antes de cualquier incluye para Boost. Pero el problema es que si no lo vuelvo a definir, entonces se confunde el otro código y no se declara "T".

Entonces pensé que tal vez podría hacer algunos trucos circulares #define así:

// some includes up here #define ___T___ T #undef T // include boost headers here #define T ___T___ #undef ___T___

Feo, pero pensé que podría funcionar.

Tristemente no. Obtengo errores en lugares usando "T" como una macro que

''___T___'' was not declared in this scope.

¿Hay alguna manera de hacer que estas dos bibliotecas funcionen de manera confiable juntas?


Entonces pensé que tal vez podría hacer algunos trucos circulares #define así:

El preprocesador C no funciona de esta manera. Los símbolos de preprocesador no están definidos en el mismo sentido en que se da un significado a un símbolo cuando, por ejemplo , se define una función.

Podría ser útil pensar en el preprocesador como un motor de reemplazo de texto. Cuando se define un símbolo, se trata como un reemplazo de texto directo hasta el final del archivo o hasta que no esté definido. Su valor no se almacena en ningún lado y, por lo tanto, no se puede copiar. Por lo tanto, la única forma de restablecer la definición de T vez que la haya #undef es reproducir completamente su valor en un nuevo #define más adelante en su código.

Lo mejor que puedes hacer es simplemente no usar Boost o solicitar a los desarrolladores de JUCE que no usen T como macro. (O, en el peor de los casos, arréglalo cambiando el nombre de la macro).


¿Puedes envolver la biblioteca ofensiva en otra inclusión y atrapar la #define T dentro?

p.ej:

JUICE_wrapper.h: #include "juice.h" #undef T main.cpp: #include "JUICE_wrapper.h" #include "boost.h" rest of code....


Como señaló Greyfade, tu truco ___T___ no funciona porque el preprocesador es una criatura bastante simple. Un enfoque alternativo es usar las directivas pragma:

// juice includes here #pragma push_macro("T") #undef T // include boost headers here #pragma pop_macro("T")

Eso debería funcionar en MSVC ++ y GCC ha agregado soporte para pop_macro y push_macro para compatibilidad con él. Técnicamente, depende de la implementación, pero no creo que haya una forma estándar de suprimir temporalmente la definición.