2011-02-05 11 views
7

Duplicar posible:
Double Negation in C++ code.¿Cuál es el propósito de un doble negativo en la definición de macro, como (!! (expr))?

estoy leyendo una base de código, y encontrar algo como esto:

#define uassert(msgid, msg, expr) (void)((!!(expr))||(uasserted(msgid, msg), 0)) 

No puedo entender por qué (!! (expr)) se usa en lugar de un solo (expr). De todos modos, un doble negativo significa positivo, ¿no? ¿Me estoy perdiendo de algo?

+0

¡Ni siquiera puedo descubrir cuál es el propósito de este código! ;) – BlackBear

+0

Como dice R, aquí es completamente inútil. – GManNickG

+0

es redundante en este caso, como usted mismo ha señalado correctamente. Tal vez fue agregado para evitar alguna advertencia del compilador. –

Respuesta

6

Es una forma de expresar el bool. Sin embargo, en C++, operador! puede estar sobrecargado Otra forma de C/C++:

C++ única manera:

static_cast<bool>(expr) 

[Editar] pensando más en C++ sobrecarga de operadores, tiene sentido para evitar el uso de los operadores. Las bibliotecas como Boost.Spirit y Boost.Lambda usan plantillas de expresión y evaluación diferida, por lo que las expresiones como (expr) || call() pueden comportarse como no se espera. La versión de prueba de balas la mayor parte de esa macro se parece a esto:

#define uassert(expr) if(expr) {} else { uasserted(...); } 

Aquí, sólo se utiliza la conversión de expr a bool. La rama else es necesaria para proteger contra expresiones como uassert(x) else something_else();.

+0

Acepte esta respuesta, porque @Maxim dio la explicación y el conocimiento adicional. – fzhang

+1

Y ahora 'uassert (expr)' ya no es una expresión; es una declaración. Esto restringe en gran medida dónde podrías usarlo.Si quieres lanzar a 'bool', simplemente lanza a' bool'. –

+0

Es una expresión de afirmación, cuyo valor es de tipo bool en la creación de depuración y nulo en la versión, supongo. ¿Podrías demostrar cuánto restringe el uso, por favor? –

1

Simplemente se asegurará de que la parte expr de la macro se convierta en bool.

+0

Hubiera sido de todos modos. – GManNickG

+0

@GMan, generalmente sí, pero quizás no. Es posible que no haya una conversión implícita a 'bool', pero hay una negación sobrecargada. –

+0

@Steven: Alguien que escribe tal clase es un idiota. Lo siento, no baso mis prácticas en lo que alguien tonto podría escribir. – GManNickG

1

Es un modismo que a veces se usa en C++ para convertir a un tipo booleano.

0

En el ejemplo que nos mostró, el !! es completamente inútil. Sin embargo, en general se usa como un equivalente bruto anterior al C99 para fundir en _Bool, es decir, 0 se queda en 0 y cualquier otro valor se convierte en 1.

+1

'!!' no es del todo inútil. '(expr) || uasserted (...) 'puede no funcionar como se espera en C++ si' || 'es un operador sobrecargado. Esta es la razón por la que (expr) se debe convertir explícitamente a boolean primero. –

+0

Gracias por recordarme por qué odio los idiomas con sobrecarga del operador (o al menos aquellos en los que los operadores que deberían tener definiciones fijas en términos de otros operadores pueden estar sobrecargados). –

+1

@Maxim: razonamiento horrible. Observe: '!!' puede no funcionar como se espera en C++ si '!' Es un operador sobrecargado. Su argumento es contraproducente: sí, alguien puede ser estúpido con los operadores, no puede ignorar convenientemente que podrían hacer lo mismo con su posición. Es inútil para cualquier programa ortodoxo, ¿a quién le importa la mierda poco ortodoxa que la gente escribe? Base sus prácticas fuera del * buen * código, por lo que termina teniendo * buenas * prácticas de programación. – GManNickG

Cuestiones relacionadas