Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected left-shift behaviour [duplicate]

Tags:

c

bit-shift

Possible Duplicate:
GCC left shift overflow

Consider the following minimal program.

#include <stdint.h>
#include <stdio.h>

int main()
{
    uint32_t v = 1024;
    v &= (((uint32_t)1 << 32) - 1);
    printf("v = %u\n", v);
    return 0;
}

This prints 1024 as I would expected compiling with GCC under MinGW. Because 1 shifted 32 times to the left is 0 again, thus 0-1 = -1 which is "1111....1111". This AND'ed with any value should return the same value again.

However, if I change the program to

#include <stdint.h>
#include <stdio.h>

int main()
{
    unsigned int s = 32;
    uint32_t v = 1024;
    v &= (((uint32_t)1 << s) - 1);
    printf("v = %u\n", v);
    return 0;
}

The result printed is now 0. Can someone explain this behaviour?

like image 355
simon Avatar asked Aug 06 '12 15:08

simon


2 Answers

Shifting a 32-bit value by 32 bits is undefined behaviour in C. Don't do it.

like image 72
Ry- Avatar answered Nov 17 '22 12:11

Ry-


Both are undefined behaviour, since the shift distance must be less than the bit-width of the type. With the constant, gcc's optimiser does what you expect, but with the variable, the shift is done at run time. Probably the shift distance is masked with 31, so no shift is done and 1 - 1 == 0.

like image 23
Daniel Fischer Avatar answered Nov 17 '22 10:11

Daniel Fischer