Let's go through the expression left-to-right:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
The first thing I notice is that we are using the ternary operator from the use of ?
. So the subexpression:
0xFULL ? '\0' : -1
is saying "if 0xFULL
is non-zero, return '\0'
, otherwise -1
. 0xFULL
is a hexadecimal literal with the unsigned long-long suffix - meaning it's a hexadecimal literal of type unsigned long long
. That doesn't really matter though, because 0xF
can fit inside a regular integer.
Also, the ternary operator converts the types of the second and third terms to their common type. '\0'
is then converted to int
, which is just 0
.
The value of 0xF
is way bigger than zero, so it passes. The expression now becomes:
a[ 0 :>>>=a<:!!0X.1P1 ]
Next, :>
is a digraph. It is a construct that expands to ]
:
a[0 ]>>=a<:!!0X.1P1 ]
>>=
is the signed right shift operator, we can space that out from a
to make it clearer.
Moreover, <:
is a digraph that expands to [
:
a[0] >>= a[!!0X.1P1 ]
0X.1P1
is a hexadecimal literal with an exponent. But no matter the value, the !!
of anything that's non-zero is true. 0X.1P1
is 0.125
which is non-zero, so it becomes:
a[0] >>= a[true]
-> a[0] >>= a[1]
The >>=
is the signed right shift operator. It changes the value of its left operand by shifting its bits forward by the value on the operator's right side. 10
in binary is 1010
. So here are the steps:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=
returns the result of its operation, so as long as shifting a[0]
remains non-zero for every time its bits are shifted right by one, the loop will continue. The fourth attempt is where a[0]
becomes 0
, so the loop is never entered.
As a result, ?
is printed three times.