telefono telefonica tarjeta pagar online mar mail macroweb macro donde cliente centro banco atencion amcro c++ c

c++ - telefonica - macroweb



¿Por qué uno usaría MACRO+0!=0 (4)

¡Hagamos una mesa!

X #if X #if X+0 != 0 <undef> false false <empty> error false 0 false false 1 true true 2 true true a false false xyz false false 12a error error 12 a error error

Entonces, la única diferencia que hemos encontrado (gracias a los comentaristas) es el caso en el que X está definido pero no tiene valor (como una cadena vacía). Nunca antes había visto la variante +0 != 0 .

En mi base de código actual veo este siguiente patrón:

#if SOMETHING_SUPPORTED+0 != 0 ... #endif

Desafortunadamente, esta es una base de código muy antigua y nadie sabe cómo y por qué comenzó. Creo que comenzó en C y se convirtió lentamente en C con clases y ahora tiende a C ++

No puedo ver ninguna ventaja obvia de usar una construcción anterior en lugar del "clásico", pero tal vez me falta algo:

#if SOMETHING_SUPPORTED ... #endif

¿Sabes por qué usaría #if MACRO+0 != 0 lugar de #if MACRO ?


Es otra forma de escribir

#if defined(MACRO) && MACRO != 0

El +0 está ahí para garantizar que el resultado sea un número. Si MACRO no está definido, evita el error de sintaxis que resultaría de #if MACRO != 0 .

Cosas de mala calidad, pero no te metas a menos que tengas que hacerlo.


La pista aquí es que la base del código es muy antigua.

Es probable que este truco exista porque el código una vez fue portado a un compilador con algún preprocesador muy antiguo que no trata las macros indefinidas como 0 en preprocesadores #if condicionales.

Es decir, a partir de 1989 ANSI C se estandarizó que si tenemos:

#if foo + bar - xyzzy

la directiva está sujeta a reemplazo de macro, de modo que si foo , bar o xyzzy son macros, se reemplazan. Luego, los identificadores restantes que no fueron reemplazados se reemplazan con 0 . Entonces, si foo se define como 42 , pero bar y xyzzy no se definen en absoluto, obtenemos:

#if 42 + 0 - 0

y no, digamos, mala sintaxis:

#if 42 + -

o algún otro comportamiento, como diagnósticos sobre la bar no definida.

En un preprocesador donde las macros indefinidas se tratan como espacios en blanco, #if SOMETHING_SUPPORTED expande a solo #if , que es erróneo.

Esta es la única forma en que este truco IDENT+0 tiene sentido real. Simplemente no querrá hacer esto si puede confiar en que el preprocesamiento cumple con la norma ISO C.

La razón es que si se espera que SOMETHING_SUPPORTED tenga valores numéricos, es erróneamente disperso para definirlo simplemente como un espacio en blanco. Lo ideal es detectar cuándo sucedió esto y detener la compilación con un diagnóstico.

En segundo lugar, si admite un uso tan sesgado, es casi seguro que desea que un símbolo explícitamente definido pero en blanco se comporte como si tuviera el valor 1, no el valor 0. De lo contrario, está creando una trampa. Alguien podría hacer esto en la línea de comando del compilador:

-DSOMETHING_SUPPORTED=$SHELL_VAR # oops, SHELL_VAR expanded to nothing

o en código:

#define SOMETHING_SUPPORTED /* oops, forgot "1" */

¡Nadie va a agregar un #define o -D para un símbolo con la intención de desactivar la función que controla! El programador que inserte un #define SOMETHING_SUPPORTED sin el 1 se sorprenderá por el comportamiento de

#if SOMETHING_SUPPORTED+0

que omite el material que se pretendía habilitar.

Es por eso que sospecho que pocos programadores de C que leen esto alguna vez han visto tal uso, y por qué sospecho que es solo una solución para el comportamiento del preprocesador cuyo efecto previsto es omitir el bloque si falta SOMETHING_SUPPORTED . El hecho de que crea una "trampa de programador" es solo un efecto secundario de la solución.

Para solucionar un problema de este tipo de preprocesador sin crear una trampa de programador es tener, en algún lugar temprano en la unidad de traducción, esto:

#ifndef SOMETHING_SUPPORTED #define SOMETHING_SUPPORTED 0 #endif

y luego en otro lugar solo use #if SOMETHING_SUPPORTED . Tal vez ese enfoque no se le ocurrió al programador original, o tal vez ese programador pensó que el truco +0 era bueno y le dio valor a su autocontención.


#if X+0 != 0 es diferente a #if X en el caso de que X se defina como vacío (nota: esto es diferente al caso de X no se define), por ejemplo:

#define X #if X // error #if X+0 != 0 // no error; test fails

Es muy común definir macros vacías: la configuración del proyecto puede generar un encabezado común que contiene un montón de líneas #define USE_FOO , #define USE_BAR para habilitar las características que admite el sistema, etc.

El != 0 es redundante, el código podría haber sido #if X+0 .

Entonces, el beneficio de usar #if X+0 es que si X se define como vacía, la compilación continúa con el bloqueo omitido, en lugar de desencadenar un error.

Si esta es una buena idea es discutible, personalmente usaría #ifdef para macros booleanas como USE_SOME_FEATURE y #if para macros donde el valor podría ser un rango de enteros, por ejemplo; y me gustaría ver un error si accidentalmente uso #if con algo definido como vacío.