Are these two lines of code equivalent?
P1->OUT &= ~(uint8_t)(1<<1);
P1->OUT &= (uint8_t)(~(1<<1));
It depends on the type of P1->OUT
, and the system. The result of 1 << 1
is of type int
.
I am considering the general case of int n;
instead of 1 << 1
In
P1->OUT &= ~(uint8_t)(n);
the operand will be widened to int
again before the ~
(the integer promotion), and the ~
would be applied to an int
. The result will have all the high-order bits 8...k set. If P1->OUT
is 8 bits wide it is OK, but if it has more bits then the result is not what you'd expect.
This one is even worse:
P1->OUT &= (uint8_t)(~(n));
The ~
operand will be applied again to an int
and that would be converted to uint8_t
. now if ~n
is actually negative (has its sign bit set) - and in case of ~(1 << 1)
it would be negative - it will be fine in two's-complement implementations but totally incorrect in 1's-complement and sign-and-magnitude implementations, because the bit representations would not be the same.
The proper way to do bit twiddling is always use unsigned int or a wider two's complement number:
P1->OUT &= ~(1U << n);
or
P1->OUT &= (~(1U << n)) & 0xFF;
to avoid the arithmetic conversions and integer promotions ever producing signed numbers.