Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS compilation warning: result of 32-bit shift implicitly converted to 64 bits

Visual Studio 2013 issues an annoying (and seemingly irrelevant) compilation warning on:

#include <stdint.h>

#define PRECISION 16

uint64_t hi = 0;
for (uint8_t i = 0; i < PRECISION; i++)
{
    if (some_condition)
    {
        hi += 1 << (PRECISION - 1 - i);
    }
}

Here is the compilation warning:

warning C4334: '<<' :
result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)

It seems to be resolved when changing 1 << (PRECISION - 1 - i) to 1 << (PRECISION - 1).

So I've been trying to figure out what could possibly go wrong in 1 << (PRECISION - 1 - i).

Obviously, if i >= PRECISION, then the shift-left operation would yield undefined behavior.

However, the variable i does not exceed the value of PRECISION - 1.

Moreover, even if we assume that the compiler cannot infer this fact, I don't see what this compilation warning has to do with a potential undefined behavior due to the shift-left operand.

Perhaps it assumes that the unsigned value of PRECISION - 1 - i can be larger than 31.

But how exactly am I supposed to tell the compiler that it never does?

I found one related question, but there are no proper answers provided.

Thanks

like image 903
barak manos Avatar asked Jan 18 '17 18:01

barak manos


1 Answers

The compiler is complaining because you store the result in a 64 bit variable so it assumes you actually wanted to do a 64 bit shift instead of a 32 bit shift. You can fix that by using

hi += 1ULL << (PRECISION - 1 - i);

To force it to be a 64 bit shift.

It would also not complain if hi was a unint32_t.

like image 175
NathanOliver Avatar answered Nov 15 '22 04:11

NathanOliver