with what va_args macro language functions define c macros c-preprocessor

what - ¿Es#if definido MACRO equivalente a#ifdef MACRO?



define max en c (5)

Si estoy leyendo su pregunta correctamente, el título es engañoso, debería ser

Is #if MACRO equivalent to #ifdef MACRO?

No son equivalentes, pero pueden (y a menudo lo son) ambos usarse para especificar modos binarios que están activados o desactivados. La elección es, en mi opinión, una cuestión de preferencia personal.

Estás usando la primera opción y ya tienes

#define verbose true

o

#define verbose false

y luego verifica el modo usando cualquiera

#if verbose

o

#if !verbose

En realidad, recomendaría que use VERDADERO o 1 en lugar de verdadero y FALSO o 0 en lugar de falso, porque verdadero y falso, son (o pueden ser) valores de C / C ++ y el preprocesador no tiene acceso a C / C ++ valores.

De todos modos, la otra forma común de especificar modos binarios es definir el indicador o dejarlo indefinido, en cuyo caso puede tener cualquiera

#define verbose any thing (including nothing) goes here

o deja fuera el #define.

y luego puedes probar si la bandera está definida, ya sea con

#ifdef verbose

o su equivalente

#if defined(verbose)

NOTA: En este caso, no está probando el valor del indicador, solo necesita probar si está definido.

Si es más conveniente, también puedes probar si la bandera no está definida con ninguno

#ifndef verbose

o su equivalente

#if !defined(verbose)

Tengo un código que quiero tener dos modos, depuración y detallado . Los defino en mi archivo de cabecera como,

#define verbose TRUE #define debug TRUE

En mi código hasta ahora, solo he estado usando

#if(debug) //code #endif

pero es más apropiado usar

#ifdef debug // code #endif

Leí algo sobre las macros del preprocesador, pero no tenía sentido en ese momento. Entonces, tengo una pregunta: ¿Es #if defined MACRO equivalente a #ifdef MACRO ? ¿y cuál es mejor para habilitar / deshabilitar una sección particular del código?


No, no son para nada equivalentes. Una rama #if MACRO se compila si MACRO evalúa a no cero. Por otro lado, una rama #ifdef MACRO se compila si se define MACRO , sin importar lo que evalúa. Asi que

#include <stdio.h> #define VAR_SET_TO_TRUE 1 #define VAR_SET_TO_FALSE 0 int main() { #if VAR_SET_TO_TRUE printf("#if VAR_SET_TO_TRUE/n"); #endif #if VAR_SET_TO_FALSE printf("#if VAR_SET_TO_FALSE/n"); #endif #if VAR_UNSET printf("#if VAR_UNSET/n"); #endif #ifdef VAR_SET_TO_TRUE printf("#ifdef VAR_SET_TO_TRUE/n"); #endif #ifdef VAR_SET_TO_FALSE printf("#ifdef VAR_SET_TO_FALSE/n"); #endif #ifdef VAR_UNSET printf("#ifdef VAR_UNSET/n"); #endif }

saldrá

#if VAR_SET_TO_TRUE #ifdef VAR_SET_TO_TRUE #ifdef VAR_SET_TO_FALSE

Tenga en cuenta que la línea printf("#ifdef VAR_SET_TO_FALSE/n"); se compila mientras que la línea printf("#if VAR_SET_TO_FALSE/n"); no es. El primero está compilado, porque VAR_SET_TO_FALSE está definido , aunque su valor sea false .


Si montamos nuestros cerebros lo suficiente, podemos encontrar una diferencia. Pero es oscuro e implica un comportamiento indefinido, por lo que no tiene importancia si lo único que nos preocupa es si el código se ajusta estrictamente a ISO C.

El #if defined ... es susceptible de comportarse de manera diferente si anteriormente se procesó una macro #define defined ... En el estándar ISO C99 fue escrito, con respecto a las directivas #if y #elif :

Antes de la evaluación, las invocaciones de macro en la lista de tokens de preprocesamiento que se convertirán en la expresión constante de control se reemplazan (excepto por los nombres de macro modificados por el operador unario definido), al igual que en el texto normal.

No se exige que el operador unario defined sea ​​reconocido y protegido de ser tratado como una macro; es solo uno de los "tokens de preprocesamiento que se convertirá en la ... expresión". El operador defined se reconoce en esta etapa solo para proteger su argumento de la expansión.

Si la definición de define como una macro simplemente se permite permanecer, y las ocurrencias de las defined se reemplazan posteriormente (incluso en los argumentos de las directivas de preprocesamiento #if ) interfiriendo así con #if defined , sin afectar a #ifdef .

Tal vez esta área del lenguaje se ajustó desde C99.


#if defined(MACRO) es lo mismo que #ifdef MACRO , pero es más largo. Por otro lado, permite agregar condiciones adicionales con || o &&

#if MACRO es similar a #ifdef MACRO pero no al 100%. Si MACRO es 0 entonces #if MACRO será negativo, requiere que se defina MACRO y que no sea 0 . #ifdef comprueba solo si está definido incluso sin valor ( #define MACRO ).

Ahora es moderno usar #if y habilitar / deshabilitar definiciones con valor 1 o 0:

#define FLAG_X 1 // or 0


#ifdef MACRO #if defined (MACRO)

hará exactamente lo mismo. Sin embargo, el definido (MACRO) es solo una expresión que evalúa a 0 o 1 dentro de #if, y se puede combinar con otras expresiones. Por ejemplo

#if defined (MACRO) && ! defined (MACRO2) // Do this #else // Do that #endif

Intenta hacer eso con #ifdef: no puedes hacerlo a menos que tu código se torne realmente torpe.