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.