VS编译警告:32位移位的结果隐式转换为64位

时间:2017-01-18 18:40:22

标签: c++ visual-studio compiler-warnings bit-shift

Visual Studio 2013在:

上发出令人烦恼(并且看似无关紧要)的编译警告
#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);
    }
}

这是编译警告:

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

1 << (PRECISION - 1 - i)更改为1 << (PRECISION - 1)时似乎已解决。

所以我一直试图找出1 << (PRECISION - 1 - i)可能出错的地方。

显然,如果i >= PRECISION,则左移操作会产生未定义的行为。

但是,变量i不会超过PRECISION - 1的值。

此外,即使我们假设编译器无法推断出这一事实,我也不会看到这个编译警告与由于左移操作数引起的潜在未定义行为有什么关系。

也许它假设PRECISION - 1 - i的无符号值可能大于31。

但我究竟应该如何告诉编译器它从来没有呢?

我找到one related question,但没有提供正确答案。

由于

2 个答案:

答案 0 :(得分:5)

编译器抱怨,因为您将结果存储在64位变量中,因此它假设您实际上想要进行64位移位而不是32位移位。你可以使用

解决这个问题
hi += 1ULL << (PRECISION - 1 - i);

强制它为64位移位。

如果hiunint32_t,也不会抱怨。

答案 1 :(得分:2)

64位的编译器indeed suspects

  

32位移位的结果被隐式转换为64位,编译器怀疑是64位移位。要解决此警告,请使用64位移位,或将移位结果显式转换为64位。

您可以考虑

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

或许删除i会抑制警告,因为编译器会将表达式视为常量。