¿Qué significa !!(x) en C (especialmente el kernel de Linux)?

4 minutos de lectura

avatar de usuario
Willi Ballenthin

He estado leyendo el kernel de Linux (específicamente, 2.6.11). Me encontré con la siguiente definición:

#define unlikely(x)     __builtin_expect(!!(x), 0)

(desde linux-2.6.11/include/linux/compiler.h:61 enlace lxr)

Que hace !! ¿lograr? ¿Por qué no usar (x)?

Ver también:

  • ¿Cómo funciona la negación lógica en C?
  • Doble negación en código C++.

  • Duplicado: stackoverflow.com/questions/248693/double-negation-in-c-code y stackoverflow.com/questions/2168406/…

    – Joel

    26 de marzo de 2010 a las 22:21


  • @Joel Potter, parece que tienes razón. Había buscado C en lugar de C++…

    – Willi Ballenthin

    26 de marzo de 2010 a las 22:25

  • @Joel: esas preguntas se relacionan con C++ y Perl, respectivamente. Si bien C ++ está al menos cerca, en la práctica los usos son al menos algo diferentes debido a que C no tiene un tipo booleano incorporado.

    – Shog9

    26 de marzo de 2010 a las 22:26


  • @ Shog9, cierto. Pero esa diferencia parece pequeña en el uso común. Si nadie más está de acuerdo, esta pregunta permanecerá abierta. 😉

    – Joel

    26 de marzo de 2010 a las 22:37

  • Este es el mensaje de confirmación que introdujo la doble negación: git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/…

    – manlio

    1 de julio de 2017 a las 10:06

avatar de usuario
pablo tomblin

!!(x) obliga a que sea 0 o 1. 0 sigue siendo 0, pero cualquier valor distinto de cero (que sería ‘verdadero’ en un contexto booleano) se convierte en 1.

  • Realmente no es necesario en este caso ya que esperamos que el resultado sea 0. Realmente solo es necesario para el #define likely(x) __builtin_expect(!!(x), 1) para asegurarse de que verdadero es 1. Es probable que solo se incluya en el unlikely Definición de simetría.

    – Chris Lutz

    26 de marzo de 2010 a las 22:21

  • Que interesante, he usado anteriormente x&&1 (o x&&YES en ObjC) para esto. Nunca pensé en usar !!.

    –Nick Moore

    26 de marzo de 2010 a las 23:09

avatar de usuario
hhafez

No es tanto una sintaxis de lenguaje sino una abreviatura común para convertir un char o int en cuasi-booleano.

En C operaciones lógicas como == && ! y así sucesivamente, puede actuar sobre int, char, etc., ya que no hay un tipo booleano; sin embargo, de acuerdo con el estándar, se garantiza que devolverán 0 para Falso y 1 para verdadero.

Entonces, por ejemplo, si tienes

int x = 5;

puede forzarlo a convertir a un tipo “booleano” (no hay un tipo booleano en C, de ahí las comillas) lo hace

x = !x; /* !5 which gives 0 always */
x = !x; /* which gives 1 always */

  • De hecho, C tiene un tipo booleano. _Bool fue introducido en C99, con una macro bool en <stdbool.h> expandiendo a _Bool. Pero los operadores lógicos incorporados como ==, &&, !et al todavía arrojan resultados de tipo int con el valor 0 o 1.

    –Keith Thompson

    20 de febrero de 2016 a las 15:36

  • “sin embargo, de acuerdo con el estándar, se garantiza que devolverán 0 para Falso y 1 para verdadero”. ¿Está seguro? Pensé que cualquier valor distinto de cero era verdadero, lo que permite optimizaciones del compilador que devuelven valores distintos de 1 para significar “verdadero”.

    – endolito

    26/10/2016 a las 18:45

avatar de usuario
miguel rebabas

!!(x) es equivalente a (x) != 0 (a menos que se esté produciendo una sobrecarga de operadores muy extraña en C++).

El hecho de que no sea obvio qué !!(x) está haciendo es probablemente una buena razón para usar (x) != 0. A menos que quieras ser un hacker de élite del kernel.

Vea esta pregunta cerrada (si todavía existe) para una discusión sobre los méritos de !! (tal vez se reabra esa pregunta, ya que esta pregunta indica que tiene algún valor).

  • No es “obvio” lo que !!(x) lo hace durante medio segundo la primera vez que lo ves. Después de verlo y a) pensarlo un poco o b) preguntarle a otra persona, reconocerá cuál es el !! “operador” lo hace con bastante rapidez.

    – Chris Lutz

    26 de marzo de 2010 a las 22:33

  • @Chris: si es un idioma común en su tienda, probablemente esté bien usarlo. Por otro lado, me encuentro !!(x) con tan poca frecuencia que tengo que hacer una pausa por un momento para asimilarlo. No tengo que cifrar por un momento acerca de lo que (x) != 0 medio. No es un gran problema, pero veo poco que recomendar. !!(x) sobre (x) != 0.

    – Michael Burr

    26 de marzo de 2010 a las 22:45

  • Lo suficientemente justo. Prefiero su apariencia, pero no hay realmente un argumento convincente para usarlo sobre (x) != 0 (a menos que necesite confiar en que algunos objetos se sobrecarguen) ! para evaluarlos en contextos booleanos).

    – Chris Lutz

    26 de marzo de 2010 a las 22:49

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad