Reputation: 89
I cannot see the difference between y
and y2
uint16_t x = 0x0F1F2;
uint8_t y = (x & 0xFF00) >> 8;
uint8_t y2 = x >> 8;
printf("%x,", y);
printf("%x,", y2);
But I see the style with a mask often. Is there ever any reason to mask with &
before doing this operation?
Upvotes: 1
Views: 4256
Reputation: 51204
In this case the mask isn't needed. There are cases when you want to mask bits, but there is no sense in masking bits that are going to be shifted away. As long as you're using unsigned
for bitwise operations, you're fine.
But since we're mentioning unsigned
, keep in mind that all types smaller than int
will be promoted to int
for bitwise and arithmetic operations, and signed int
kinda sucks. Left shifting a signed int
which would lead to an overflow is undefined behavior. Right shifting will usually be implemented as an aritmetic shift (implementation dependant -- but usually it will repeat the sign bit when right-shifting), and this can surprise people at times:
uint16_t x = 0xF123;
uint32_t y = (x << 16) >> 16; // implementation-dependant, but likely 0xFFFFF123
uint32_t z = (x << 28); // undefined behavior
Upvotes: 1
Reputation: 690
Typically you might mask before if some bits represent an integer stored in the value. This would probably be a hardware or network interface. So you might have the bit mask of 0xff00 defined, and a shift count, so you mask first then shift.
As for your example, y
and y2
are the same, and if you compile and optimize (possibly in separate compilations), the code generated should be the same. (And will almost certainly not contain a shift operation, as it just needs to read the right byte.)
Upvotes: 2