very weird bit behaviour

Hi, like the title says I'm facing very weird behavior when trying to manipulate some bits. This happens only in VS 2015, in other places everything works fine ( getting result 00000000 00000000 00000000 00000000)

Why is line 9 giving me this behaviour in VS 2015?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

void print_bits(int val);

int main()
{
	int n = 32;
        print_bits((~0) << 32); //given this I get 00000000 00000000 00000000 00000000
        print_bits((~0) << n); //given this I get 11111111 11111111 11111111 11111111
}

void print_bits(int val)
{
	for (int i = sizeof(int) * 8 - 1; i >= 0; --i)
	{
		if ((1 << i) & val)
			std::cout << 1;
		else
			std::cout << 0;
		if (!(i % 8))
			std::cout << " ";
	}
	std::cout << "\n";
}


PS in the same time this works fine
1
2
	int n = 31;
        print_bits((~0) << n); //given this I get 10000000 00000000 00000000 00000000 

Last edited on
It is undefined behavior in C++ (and in C) to shift left by the entire width of the type. See http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators for the effects of shift operators in detail.

clang and gcc will warn you:
1
2
3
main.cpp:8:25: warning: shift count >= width of type [-Wshift-count-overflow]
        print_bits((~0) << 32); //given this I get 00000000 00000000 00000000 00000000
                        ^  ~~


1
2
3
main.cpp:8:28: warning: left shift count >= width of type [-Wshift-count-overflow]
         print_bits((~0) << 32); //given this I get 00000000 00000000 00000000 00000000
                            ^


since the behavior is undefined, there is absolutely no guarantee for anything the program does in this case.
Looking at the ASM from my compiler the (~0) << 32 is baked in, whereas the (~0) << n gets computed at runtime. (the baked in version treats the computation differently, probably because of what Cubbi mentioned)
Last edited on
Thanks you guys very much, did not know about this :)
Topic archived. No new replies allowed.