-1

I'm trying to create a mask, but when I calculate the value of shift and put it inside a variable I get the wrong result. Look:

#include <stdio.h>

int main(){
        int shift = 32 ;
        printf("%d\n",shift);   //32
        int mask = 0xFFFFFFFF << shift;
        printf("%x\n",mask);     //ffffffff      
        mask = 0xFFFFFFFF << 32;
        printf("%x\n",mask); //00000000
        return 0;
}

Someone knows why this is happening?

  • 1
    Yeah, undefined behaviour will do that. FWIW, Clang gives me 0 and 0, as well as a warning. That changes to 4005b6 and 4005ba when compiling it as C. – chris Jun 06 '15 at 01:21
  • _"The wrong result"_ Huh well since the code does what the code does, by definition, we cannot magically divine what you mistakenly thought might otherwise happen. So, wow, shock horror, you might have to actually tell us what you erroneously assumed before we can even begin to help. – Lightness Races in Orbit Jun 06 '15 at 03:56

1 Answers1

4

If your system has 32-bit or smaller int, then you cause undefined behaviour by shifting by 32 bits or more. Shifts must be by a fewer number of bits than the type has.

If you have 64-bit int then 0xFFFFFFFF will be a signed int, and shifting it by 32 bits will move a 1 into the sign bit, which causes UB in C, and in C++ prior to C++14. (Since C++14 this causes implementation-defined behaviour).

printf("%x\n",mask); would also trigger UB if the shift went as planned in the 64-bit case, because %x requires non-negative values but you'd be passing a negative int. To avoid this , use unsigned int mask instead.

When you have triggered UB anything can happen, including but not limited to nonsense output, and the same operation giving different results.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • The second point isn't happening. 0xFFFFFFFF is an `unsigned int` assuming it can fit in that and not an `int` (see [lex.icon]/2). – chris Jun 06 '15 at 01:50
  • Hooray for digit separators? :) I mean using one of the actual max unsigned int constants would be clearer, but still. – chris Jun 06 '15 at 01:52