Qué es la operación &&& en C

195
#include <stdio.h>

volatile int i;

int main()
{
    int c;

    for (i = 0; i < 3; i++) 
    {
         c = i &&& i;
         printf("%d\n", c);
    }

    return 0;
}

El resultado del programa anterior compilado usando gcces

0
1
1

Con la opción -Wallo -Waddress, gccemite una advertencia:

warning: the address of i will always evaluate as true [-Waddress]

¿Cómo se cevalúa en el programa anterior?

manav mn
fuente
42
Creo que es i && (&i)? Es interesante que no pueda encontrar una publicación duplicada en SO.
irrelefante
42
while (i &&& i <-- j) {}.
kennytm
8
No es un duplicado, pero es una pregunta similar y ese es un buen enlace
Nathan Cooper

Respuestas:

272

Es c = i && (&i);, con la segunda parte siendo redundante, ya &ique nunca se evaluará false.

Para un tipo definido por el usuario, donde realmente puede sobrecargar unario operator &, puede ser diferente, pero sigue siendo una muy mala idea .

Si activa las advertencias , obtendrá algo como:

advertencia: la dirección de 'i' siempre se evaluará como 'verdadero'

Luchian Grigore
fuente
1
¿Por qué no: c = i & (&&i);; ¿Dónde iestá alguna etiqueta?
anishsane
44
@anishsane ise define como inty no hay etiquetas en la pregunta. Además, munch máximo ...
Luchian Grigore
55
@anishsane: Y el &&operador que toma la dirección de una etiqueta es una extensión gcc no estándar de todos modos. Pero incluso si fuera estándar, la regla de munch máxima evitaría que se analizara de esa manera (a menos que inserte un espacio).
Keith Thompson
En realidad, &ipuede evaluar a false. A veces se usa para valores predeterminados. Ejemplo: void fn(type& x = *reinterpret_cast<type*>(NULL)); ¿Cuál es el valor de &xin fnsi fnse llama sin parámetros? Es 0 aka falso. Sin embargo, usándolo de la manera descrita, siempre será cierto a menos que i == 0, y si uno lo estuviera utilizando como lo describí, lo sería c = &i && i.
Adrian
@LuchianGrigore: ¿cómo es eso?
Adrian
118

No hay &&&operador o token en C. Pero el &&(lógico "y") y& (dirección unaria de o bit a bit "y") existen.

Por la regla de munch máxima , esto:

c = i &&& i;

es equivalente a esto:

c = i && & i;

Se establece cen 1 si ambos iy&i son verdaderas, y 0 si alguno de ellos es falso.

Para un int, cualquier valor distinto de cero es verdadero. Para un puntero, cualquier valor no nulo es verdadero (y la dirección de un objeto siempre es no nulo). Entonces:

Se establece cen 1 si ino es cero, o 0sii es igual a cero.

Lo que implica que &&&se está utilizando aquí solo para ofuscación deliberada. La asignación podría ser cualquiera de los siguientes:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++
Keith Thompson
fuente