C - Seemingly unsigned int being sign extended when right shift?

648 views Asked by At

So I was trying to test out a super short function for getting me the integer value of certain bits x through y from an integer, but am having some trouble with the sign extension that is happening. I tried casting to an unsigned int and then shifting using the unsigned int, but that does not seem to be working. The code is the following:

#include <stdio.h>

int main()
{
    int bo_bits = 2;
    int tag_bits = 28;
    int addr = 1;

    unsigned int index = (unsigned int)addr;
    index = index << tag_bits;
    index = index >> bo_bits;

    // at this point I would return (int)index;

    return 0;
}

I don't understand why there is sign extension that is occurring, as I have shifted only on an unsigned integer. I also ran the code using just "addr" and had it as an unsigned int, but that didn't change the output either.

The output value for index is 536870912 when I run the function in gdb on a linux machine, and on compile online (now coding ground), the value that I get is 67108864.

Edit: A couple people have asked how I got the value 536870912, I have gotten it running gdb through both breakpoints and running the command p get_index(1) from gdb. The actual code is the following:

unsigned int index = (unsigned int)addr;
index = index << tag_bits;
index = index >> bo_bits;
return (int)index;

Thanks for all the help!

1

There are 1 answers

0
simon_xia On

536870912 is equal to 1 << 29, which means it has nothing to do with sign extension.

maybe it is you who stop at the wrong place when debuging the program

here is what c99 standard says about bitwise right shift. (6.5.7 Bitwise shift operators)

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.