(Visual C ++ v141)按位函数编译错误

时间:2017-05-09 02:44:37

标签: c++ visual-studio visual-c++

在工具集v141上使用Visual Studio Enterprise 2017版本15.1(26403.7)。

以下代码似乎编译错误。

#define GMASK(rangeStart, rangeEnd) ((1 << (rangeEnd - rangeStart + 1)) - 1)
uint32_t _gmask(uint32_t rangeStart, uint32_t rangeEnd)
{
    return ((1 << (rangeEnd - rangeStart + 1)) - 1);
}

int main()
{
    cout << bitset<32>(GMASK(0, 31)) << endl;
    cout << bitset<32>(_gmask(0, 31)) << endl;

    return 0;
}

在Visual Studio中,输出为

11111111111111111111111111111111
00000000000000000000000000000000

但是在gcc中,输出是

11111111111111111111111111111111
11111111111111111111111111111111

为什么输出相同的代码时会有差异?

1 个答案:

答案 0 :(得分:1)

这是未定义的行为。

在您的代码中,当计算_gmask(0, 31)时,使用值2 32 。这已经超出了uint32_t的范围,范围从0到2 32 -1。

从C ++ 14开始5.8移位运算符:

  

E1的值<&lt; E2是E1左移E2位位置;空位是零填充的。如果E1具有无符号类型,则结果的值为E1×2 E2 ,以比可表示的最大值减1的模数   在结果类型中。否则,如果E1具有有符号类型和非负值,并且E1×2 E2 可在结果类型的相应无符号类型中表示,则转换为结果类型的该值是结果价值;否则,行为未定义。