Veamos la expresión de izquierda a derecha:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
Lo primero que noto es que estamos usando el operador ternario del uso de ?
. Entonces la subexpresión:
0xFULL ? '\0' : -1
dice "si 0xFULL
no es cero, return '\0'
, de lo contrario -1
. 0xFULL
es un literal hexadecimal con el sufijo largo largo sin signo , lo que significa que es un literal hexadecimal de tipo unsigned long long
. Sin embargo, eso realmente no importa, porque 0xF
puede caber dentro de un entero regular.
Además, el operador ternario convierte los tipos del segundo y tercer término a su tipo común. '\0'
luego se convierte a int
, que es justo 0
.
El valor de 0xF
es mucho mayor que cero, por lo que pasa. La expresión ahora se convierte en:
a[ 0 :>>>=a<:!!0X.1P1 ]
A continuación, :>
hay un dígrafo . Es una construcción que se expande a ]
:
a[0 ]>>=a<:!!0X.1P1 ]
>>=
es el operador de desplazamiento a la derecha firmado, podemos espaciarlo a
para aclararlo.
Además, <:
es un dígrafo que se expande a [
:
a[0] >>= a[!!0X.1P1 ]
0X.1P1
es un literal hexadecimal con un exponente. Pero no importa el valor, !!
todo lo que no sea cero es cierto. 0X.1P1
es 0.125
que no es cero, por lo que se convierte en:
a[0] >>= a[true]
-> a[0] >>= a[1]
El >>=
es el operador de desplazamiento a la derecha firmado. Cambia el valor de su operando izquierdo desplazando sus bits hacia adelante por el valor en el lado derecho del operador. 10
en binario es 1010
. Así que aquí están los pasos:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=
devuelve el resultado de su operación, de modo que mientras el desplazamiento a[0]
permanezca distinto de cero por cada vez que sus bits se desplacen uno a la derecha, el bucle continuará. El cuarto intento es donde se a[0]
hace 0
, por lo que el ciclo nunca se ingresa.
Como resultado, ?
se imprime tres veces.