左转与GCC严重错误

0 c++ gcc bit-shift

我一直在看这段代码一小时......我拼命想找到错误.

#include <iostream>

int main()
{
    for (int32_t n = 1; n>= 0; n--)
    {
        std::cout << "n: " << n << std::endl;
        std::cout << std::dec << "  64 - n: " << (64 - n) << std::endl;
        std::cout << std::hex << "  0x1ULL << 64: " << (0x1ULL << 64) << std::endl;
        std::cout << std::hex << "  0x1ULL << (64 - n): " << (0x1ULL << (64 - n)) << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

那是输出:

n: 1
  64 - n: 63
  0x1ULL << 64: 0
  0x1ULL << (64 - n): 8000000000000000
n: 0
  64 - n: 64
  0x1ULL << 64: 0
  0x1ULL << (64 - n): 1
Run Code Online (Sandbox Code Playgroud)

为什么(0x1ULL << 64)与(0x1ULL <<(64-n))不同,n = 0?n的类型似乎并不重要.

每个版本的GCC都是一样的.欢迎在线试用:http: //www.compileonline.com/compile_cpp11_online.php

Mik*_*our 8

您有未定义的行为:

C++ 11 5.8/1如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义.

因此,假设long long有64位,移位64位将给出未定义的行为.

  • @ user3497687:实际上,这个规则是因为创建它的人*确实知道当一个移位溢出时不同的处理器以不同的方式运行; 所以指定行为会增加自然表现不同的处理器的工作量.GCC不会"增加努力" - 它只使用原生的移位操作,并提供产生的任何结果. (5认同)