Search code examples
c++bit-manipulationbitwise-operatorsconstexpr

Is there a limit of n bits when bit shifting?


While trying to come up with a scheme for a bitboard class, I decided use global compile time variables to represent key bit board configurations, ex. the initial position of all black rooks.

constexpr uint64_t BLACK_ROOK_INIT  = 0x1 | (0x1 << 56);

However I am getting compiler errors. The compiler appears to be treating this value as a 32 bit value and type casting or adding additional 0's does not seem to make a difference. The type definition is from .

As soon as I drop constexp from this expression it compiles, however still produces the equivalent warning. Why is this happening? I thought it might be a limitation of the pre-processor, but the problem persists without constexp.

chess.cpp:16:64: error: right operand of shift expression ‘(1 << 56)’ is >= than the precision of the left operand [-fpermissive]

FYI, this also does not compile

constexpr int64_t BLACK_ROOK_INIT = (int64_t)0x1 | (int64_t)(0x1 << 32);

Solution

  • This is what you want:

    #include <iostream>
    
    int main(){
      constexpr uint64_t BLACK_ROOK_INIT  = 0x1ULL | (0x1ULL << 56);
      std::cout<<BLACK_ROOK_INIT<<std::endl;
    }
    

    Your 0x1 value is, by default, an int, which is usually implemented as a 32-bit integer.

    The suffixes are discussed here. If they make you a bit uncomfortable, as they do me, you can cast as follows:

    #include <iostream>
    
    int main(){
      constexpr uint64_t BLACK_ROOK_INIT  = (uint64_t)(0x1) | ((uint64_t)(0x1) << 56);
      std::cout<<BLACK_ROOK_INIT<<std::endl;
    }