以下代码输出0、1、32、33。至少可以说这是反直觉的。但是,如果将文字1替换为带注释的常量“ONE”,则循环运行良好。

这是与gcc 4.6.2和-std = c++ 0x一起使用的。

#include<iostream>
#include<cstdint>
using namespace std;
int main()
    {
    int64_t bitmask = 3;
    int64_t k;
    const int64_t ONE = 1;
    cout<<"bitmask = "<<bitmask<<endl;

    for(k=0; k<64; k++)
        {
        if(bitmask & (1<<k))
            {
            cout<<"k="<<k<<endl;
            }
        }

    return 0;
    }

编辑
问题:正如Ben指出的那样,默认情况下1被视为32位宽。当合作数为64位时为什么不将其提升为64位。

解决方案

否。<
复制自比尔(Bill)的以下评论

最佳答案

这是一个问题:(1<<k)
1是适合int的整数文字。

如果平台上的int少于64位,则当(1<<k)很大时,k将在循环结束时具有未定义的行为。在您的情况下,编译器使用Intel位移位指令,并且未定义的行为以Intel定义的移位大于操作数大小的方式出现-高位被忽略。

您可能需要(1LL<<k)
标准说了什么(第5.8节expr.shift):



这与“通常的算术转换是针对
算术或枚举类型的操作数。”,例如加减运算符。

在C++ 03和C++ 11之间,该语言没有变化。

09-09 18:59