Passons en revue l'expression de gauche à droite:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
La première chose que je remarque, c'est que nous utilisons l'opérateur ternaire depuis l'utilisation de ?
. Donc, la sous-expression:
0xFULL ? '\0' : -1
dit "si 0xFULL
est différent de zéro, retour '\0'
, sinon -1
. 0xFULL
est un littéral hexadécimal avec le suffixe long-long non signé - ce qui signifie que c'est un littéral hexadécimal de typeunsigned long long
. Cela n'a pas vraiment d'importance, car 0xF
peut tenir dans un entier normal.
De plus, l'opérateur ternaire convertit les types des deuxième et troisième termes en leur type commun. '\0'
est ensuite converti en int
, qui est juste0
.
La valeur de 0xF
est bien supérieure à zéro, elle passe donc. L'expression devient maintenant:
a[ 0 :>>>=a<:!!0X.1P1 ]
Ensuite, :>
est un digraphe . C'est une construction qui se développe pour ]
:
a[0 ]>>=a<:!!0X.1P1 ]
>>=
est l'opérateur de décalage à droite signé, nous pouvons espacer cela a
pour le rendre plus clair.
De plus, <:
est un digraphe qui se développe pour [
:
a[0] >>= a[!!0X.1P1 ]
0X.1P1
est un littéral hexadécimal avec un exposant. Mais peu importe la valeur, la valeur !!
de tout ce qui n'est pas nul est vraie. 0X.1P1
est 0.125
qui est non nul, il devient donc:
a[0] >>= a[true]
-> a[0] >>= a[1]
Le >>=
est l'opérateur de décalage vers la droite signé. Il modifie la valeur de son opérande gauche en décalant ses bits vers l'avant de la valeur sur le côté droit de l'opérateur. 10
en binaire est 1010
. Voici donc les étapes:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=
renvoie le résultat de son fonctionnement, de sorte que tant que le décalage a[0]
reste non nul à chaque fois que ses bits sont décalés de un vers la droite, la boucle continue. La quatrième tentative est où a[0]
devient 0
, donc la boucle n'est jamais entrée.
Par conséquent, ?
est imprimé trois fois.