Перейдемо до виразу зліва направо:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
Перше, що я помічаю - це те, що ми використовуємо потрійного оператора з використання ?. Отже, підвираз:
0xFULL ? '\0' : -1
говорить "якщо 0xFULLце не нульове значення, поверніться '\0', інакше -1." 0xFULL- це шістнадцятковий буквал з неподписаним суфіксом "довгий" - це означає, що це шістнадцятковий буквальний тип unsigned long long. Однак це не має значення, оскільки 0xFможе міститись у звичайному цілому.
Також потрійний оператор перетворює типи другого та третього доданків у їх загальний тип. '\0'потім перетворюється на int, що справедливо 0.
Значення 0xFє набагато більшим за нуль, тому воно проходить. Вираз зараз стає:
a[ 0 :>>>=a<:!!0X.1P1 ]
Далі :>- диграф . Це конструкція, яка розширюється на ]:
a[0 ]>>=a<:!!0X.1P1 ]
>>=це підписаний оператор правої зміни, ми можемо виділити це, aщоб зробити його зрозумілішим.
Більше того, <:це диграф, який розширюється на [:
a[0] >>= a[!!0X.1P1 ]
0X.1P1є шістнадцятковим буквалом із експонентом. Але незалежно від цінності, !!все, що є не нульовим, є правдою. 0X.1P1це 0.125який не дорівнює нулю, тому вона стає:
a[0] >>= a[true]
-> a[0] >>= a[1]
Це >>=підписаний оператор правої зміни. Він змінює значення лівого операнда, переміщуючи його біти вперед на значення з правого боку оператора. 10у двійковій є 1010. Отже ось такі кроки:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=повертає результат своєї роботи, доки зміщення a[0]залишається ненульовим щоразу, коли його біти зміщуються вправо на один, цикл продовжуватиметься. Четверта спроба - де a[0]стає 0, тому цикл ніколи не вводиться.
Як результат, ?друкується три рази.