Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected bitshift behavior in C [duplicate]

I am currently trying to extract some bits from an address called addr with a 32 bit mask called mask into another variable called result as follows

int addr = 7;
int x = 0;
uint32_t mask = 0xFFFFFFFF;
result = addr & (mask >> (32 - x));

I am expecting result to be 0 when x = 0, and this is confirmed on online bitshift calculators. however in C code, result is 1. Why is that?

like image 753
DanielJomaa Avatar asked Dec 21 '25 18:12

DanielJomaa


2 Answers

You're performing an illegal bitshift.

Shifting by a value greater or equal than the size in bits of the left operand results in undefined behavior. This is documented in section 6.5.7p3 of the C standard:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

This means you need to check the value of x, and if it is 0 then just use 0 for the bitmask.

int x = 0;
uint32_t mask = 0xFFFFFFFF;
...
if (x == 0) {
    result = 0;
} else {
    result = addr & (mask >> (32 - x));
}
like image 183
dbush Avatar answered Dec 23 '25 06:12

dbush


From the C standard (6.5.7 Bitwise shift operators)

3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined

like image 44
Vlad from Moscow Avatar answered Dec 23 '25 07:12

Vlad from Moscow