tag - meta title y meta descripcion
¿Por qué usar !!(condición) en lugar de(condición)? (4)
¡El unario !
El operador de negación lógica, aplicado a cualquier escalar, produce el valor int
0
si su operando no es cero, 1
si el operando es igual a cero. Citando el estándar:
La expresión
!E
es equivalente a(0==E)
.
Aplicando !
dos veces al mismo valor escalar arroja un resultado que es falso si el valor es falso, verdadero si el valor es verdadero, pero el resultado se normaliza a 0
o 1
, respectivamente.
En la mayoría de los casos, esto no es necesario, ya que cualquier valor escalar se puede usar directamente como una condición. Pero en algunos casos, realmente necesitas un valor de 0
o 1
.
En C99 o posterior, convertir la expresión en _Bool
(o bool
si tiene #include <stdbool.h>
comporta de manera similar y se puede considerar más claro. Pero (a) el resultado es de tipo _Bool
lugar de int
, y (b) si está utilizando un compilador anterior a C99 que no admite _Bool
y ha definido su propio tipo de bool
, no se comportará del mismo modo que el _Bool
de C99.
Esta pregunta ya tiene una respuesta aquí:
He visto código donde las personas han usado cláusulas condicionales con dos ''!'' S
#define check_bit(var, pos) (!!((var) & (1 << (pos))))
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
son algunos de los ejemplos que pude encontrar.
¿Hay alguna ventaja en usar !!(condition)
sobre (condition)
?
Bueno, si la variable que está aplicando !!
ya no es un bool
( cero o uno ), entonces normalizará el valor a 0
o 1
.
Con respecto a __builtin_expect
este hilo de novatos kernel discute la notación y una de las respuestas explica ( énfasis mío ):
La firma de __builtin_expect
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html ) es:
largo __builtin_expect (exp largo, c largo)
Tenga en cuenta que el parámetro exp debe ser una expresión integral, por lo tanto no hay punteros o tipos de punto flotante allí. La doble negación maneja la conversión de estos tipos a expresiones integrales automáticamente . De esta manera, simplemente puede escribir: likely (ptr) en lugar de likely (ptr! = NULL) .
Para referencia en C99, la macro bool
expande a _Bool
, true
expande a 1
y false
expande a 0
. Los detalles se dan en el borrador de la sección estándar 7.16
tipo booleano y valores .
La negación lógica se cubre en 6.5.3.3
Operadores aritméticos unarios en el párrafo 5 :
¡El resultado del operador de negación lógica! es 0 si el valor de su operando se compara desigual a 0, 1 si el valor de su operando se compara con 0. El resultado tiene tipo int. La expresión! E es equivalente a (0 == E).
Lo más grande que puedo ver es que forzará (o normalizará) el valor en 1
o 0
(que es un valor booleano) independientemente de cómo se expanda la expresión xo var
(por ejemplo, char
o double
o int
etc.).
Se lanza a un booleano, que a veces puede ser útil.