test tag else descripcion c logical-operators

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.