Yyao
Yyao

Reputation: 413

Why do `1 << 32` and `int i=32; 1 << i` show different result? Is it a bug or feature?

The code is shown as follow. I tested it on VS, clang++ and G++. All of them show that 1 << 32 and 1 << i(where i is 32) is different. I took a look at the assemble. It looks like the compiler compute the result of 1 << 32 in compiling. I think this inconsistency should be a bug or it is just another undefined behavior of C++.

#include <iostream>

int main(int argc, char *argv[])
{
    std::cout << (1 << 32) << std::endl;
    int i = 32;
    std::cout << (1 << i) << std::endl;
    return 0;
}

Results:

clang++:
1 << 32:73832
1 << i:1
g++:
1 << 32:73832
1 << i:1

Upvotes: 3

Views: 4547

Answers (3)

Giorgi Moniava
Giorgi Moniava

Reputation: 28684

std::cout << (1 << 32) << std::endl;

This is undefined behavior if int is 4 bytes on your system. From the standard (section about shift operators):

The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

Upvotes: 8

haccks
haccks

Reputation: 106092

C++ standard says

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1×2^E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

and then

The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

In this case you shouldn't expect any good.

Upvotes: 3

Both operands to << are ints, and thus result is int. If int is maximum 32 bits wide, a signed integer overflow happens in both cases; signed integer overflow always has had undefined behaviour in both C and C++.

However, many people mistakenly believe that the undefined behaviour means that the result is some "unspecified int" or that on their platform the result is 1 << 32 (mod 2³²); however the truth is that on 64-bit platforms compilers tend to use 64-bit registers for 32-bit calculations, knowing that the calculation never can overflow in a conforming program, so in case of undefined behaviour the actual result can also be a value that does not even fit in a 32-bit variable!

Upvotes: 2

Related Questions