with sirve que para macro ifdef elif ejemplo dev define c++ c-preprocessor

sirve - file c++



¿Por qué el preprocesador C considera los valores de enumeración como iguales? (7)

Como decían las otras respuestas, el preprocesador C no ve enumeraciones. Espera, y solo puede entender, macros.

Según el estándar C99 , §6.10.1 (inclusión condicional):

Después de que se hayan realizado todos los reemplazos debido a la expansión de macro y el operador unario definido, todos los identificadores restantes se reemplazan con el número pp 0

En otras palabras, en una directiva #if o #elif, las macros que no se pueden expandir, porque no existen / no están definidas, se comportarán exactamente como si se hubieran definido como 0 y, por lo tanto, siempre serán iguales a El uno al otro.

Puede detectar comportamientos no deseados como este en GCC / clang con la opción de advertencia -Wundef (probablemente querrá hacerlo fatal con -Werror = undef).

¿Por qué se ejecuta la línea std::cout en el siguiente código aunque A y B son diferentes?

#include <iostream> enum T { A = 1, B = 2 }; // #define A 1 // #define B 2 int main() { #if (A == B) std::cout << A << B; #endif }

Si uso #define lugar (como se comentó), no obtengo ningún resultado como esperaba.

Motivo de la pregunta:

Quiero tener un selector de modo para algún código de prueba en el que pueda cambiar fácilmente los modos comentando / descomentando líneas en la parte superior:

enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 }; // #define MODE MODE_RGB #define MODE MODE_GREY // #define MODE MODE_CMYK int main() { #if (MODE == MODE_RGB) // do RGB stuff #elif (MODE == MODE_GREY) // do greyscale stuff #else // do CMYK stuff #endif // some common code some_function(arg1, arg2, #if (MODE == MODE_RGB) // RGB calculation for arg3, #elif (MODE == MODE_GREY) // greyscale calculation for arg3, #else // CMYK calculation for arg3, #endif arg4, arg5); }

Sé que puedo usar valores numéricos, por ejemplo

#define MODE 1 // RGB ... #if (MODE == 1) // RGB

pero hace que el código sea menos legible.

¿Hay una solución elegante para esto?


El preprocesador se ejecuta antes que el compilador, lo que significa que el preprocesador no sabe nada sobre los símbolos definidos por el compilador y, por lo tanto, no puede actuar dependiendo de ellos.


Esto se debe a que el preprocesador funciona antes del tiempo de compilación.

Como las definiciones de enumeración se producen en el momento de la compilación, A y B se definirán como vacías (número de pp 0 ), y por lo tanto iguales, en el tiempo de preprocesamiento, y por lo tanto la declaración de salida se incluye en el código compilado.

Cuando usa #define , se definen de manera diferente en el tiempo de procesamiento previo y, por lo tanto, la declaración se evalúa como falsa.

En relación con su comentario sobre lo que desea hacer, no necesita usar el preprocesador #if para hacerlo. Puede usar el estándar if MODE y MODE_GREY (o MODE_RGB o MODE_CMYK ) todavía están definidos:

#include <iostream> enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 }; #define MODE MODE_GREY int main() { if( MODE == MODE_GREY ) std::cout << "Grey mode" << std::endl; else if( MODE == MODE_RGB ) std::cout << "RGB mode" << std::endl; else if( MODE == MODE_CMYK ) std::cout << "CMYK mode" << std::endl; return 0; }

La otra opción que usa solo el preprocesador es hacer esto como @TripeHound respondió correctamente a continuación .


Las publicaciones explican por qué, pero una posible solución para usted que mantiene la legibilidad podría ser así

#define MODE_RGB int main() { #ifdef MODE_RGB std::cout << "RGB mode" << std::endl; #elif defined MODE_GREY std::cout << "Grey mode" << std::endl; #elif defined MODE_CMYK std::cout << "CMYK mode" << std::endl; #endif }

Solo necesita cambiar la macro en la parte superior, solo se define la macro que le interesa. También puede incluir una verificación para asegurarse de que uno y solo uno esté definido y, si no, y hacer #error "You must define MODE_RGB, MODE_GREY or MODE_CMYK


Los identificadores que no son macros definidos se interpretan como valor 0 en las directivas de preprocesador condicional. Por lo tanto, dado que no había definido las macros A y B , ambas se consideran 0 y dos 0 son iguales entre sí.

La razón por la cual los identificadores indefinidos (para el preprocesador) se consideran 0 es porque permite usar macros indefinidas en el condicional sin usar #ifdef .


No hay macros llamadas A o B , por lo que en su línea #if , A y B se reemplazan por 0 , por lo que en realidad tiene:

enum T { A = 1, B = 2 }; int main() { #if (0 == 0) std::cout << A << B; #endif }

El preprocesador se ejecuta antes de que el compilador sepa algo sobre su enum . El preprocesador solo conoce las macros ( #define ).


Otras respuestas explican por qué lo que estás intentando no funciona; para una alternativa, probablemente iría con:

#define RGB 1 #define GREY 2 #define CMYK 3 #define MODE RGB #if MODE == RGB //RGB-mode code #elif MODE == GREY //Greyscale code #elif MODE == CMYK //CMYK code #else # error Undefined MODE #endif

Es posible que desee prefijos en RGB / GREY / CMYK si existe el peligro de conflictos con el código fuente "real".