I'd recommend you to split this long line into few small pieces (sometimes it is more effective to try such things; i.e. reading of the documentation only is not enough):
int x = 2;
printf("%d\n", x); // prints 2
printf("%d\n", x << x); // prints 8
printf("%d\n", x << x << x); // prints 32
printf("%d\n", !!x); // prints 1
printf("%d\n", x << !!x); // prints 4
printf("%d\n", x); // prints 2 (just to become sure that x was not changed)
So, you know that initial long line is equal to x = (32 | 32 | 1 | 4)
. But this is 32+4+1=37.
Let's see in details:
What is <<
and >>
?
The shift operators bitwise shift the value on their left by the number of bits on their right:
<<
shifts left and adds zeros at the right end.
>>
shifts right and adds either 0s, if value is an unsigned type, or extends the top bit (to preserve the sign) if its a signed type.
Also the C standard says about E1 >> E2: "If E1 has a signed type and a negative value, the resulting value is implementation-defined." Arithmetic shift is not guaranteed.
Since <<
is left associative, x<<x<<x
is evaluated as (x<<x)<<x
.
See also: What are bitwise shift (bit-shift) operators and how do they work?
What is !!x
?
It is an unary NOT and an unary NOT.
!!x
can be used as shorthand for (x != 0 ? 1 : 0)
.