Давайте пройдемся по выражению слева направо:
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, поэтому цикл никогда не вводится.
В результате ?печатается три раза.