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
!Ees 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.