Boost::integer_mask GCC编译错误

boost::integer_mask gcc compiler error

本文关键字:编译 错误 GCC integer Boost mask      更新时间:2023-10-16

我无法编译以下代码(使用boost 1.61)。

#include <boost/integer/integer_mask.hpp>
#include <iostream>
int main() {
    uint a =  boost::low_bits_mask_t<1>::sig_bits;
    std::cout << "bitmask " << a << std::endl;
}

在clang上它可以很好地编译。
使用g++(版本6.2.1),我得到

 file included from /usr/include/boost/config.hpp:61:0,
                 from /usr/include/boost/integer_fwd.hpp:15,
                 from /usr/include/boost/integer/integer_mask.hpp:13,
                 from boostbug.cpp:1:
/usr/include/boost/integer/integer_mask.hpp: In instantiation of ‘const least boost::low_bits_mask_t<1ul>::sig_bits’:
boostbug.cpp:7:42:   required from here
/usr/include/boost/integer/integer_mask.hpp:66:5: error: left operand of shift expression ‘(-1 << 1ul)’ is negative [-fpermissive]
     BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
     ^

我做错了什么?
这是一个gcc bug还是一个boost bug?

分析~(least( 0u )) << Bits表达式。为什么这个变成了-1?首先,least类型将是可以容纳您想要的位数(1)的最小类型。这将是unsigned char,因此表达式现在看起来像~(unsigned char( 0u )) << Bits~运算符将执行积分提升。这将导致unsigned char被提升为int(有符号),因为该类型是unsigned char可以提升到的类型列表中的第一个类型,并且它将保存所有可能的值。1的补码为0,在使用2补码的系统中被解释为有符号整数时为-1。负整数的左移是一种未定义的行为,这就是为什么你会看到这样的错误。

sig_bits_fast也有同样的问题,所以没有提供解决方案。

这是一个boost错误,因为boost头代码依赖于未定义的行为(有符号量的左移)。

我不认为你做错了什么。这显然是编译器错误。我用在线http://cpp.sh/编译器编译了你的代码。

我也可以在VS2015和boost 1.58中检查它。

#include <boost/integer/integer_mask.hpp>
#include <iostream>
int main()
{
  uint a0 =  boost::low_bits_mask_t<0>::sig_bits;
  std::cout << "bitmask <0> = " << a0 << std::endl;   
  uint a =  boost::low_bits_mask_t<1>::sig_bits;
  std::cout << "bitmask <1> = " << a << std::endl;    
  uint b =  boost::low_bits_mask_t<2>::sig_bits;    
  std::cout << "bitmask <2> = " << b << std::endl;   
  uint c =  boost::low_bits_mask_t<3>::sig_bits;    
  std::cout << "bitmask <3> = " << c << std::endl;   
  uint d =  boost::low_bits_mask_t<4>::sig_bits;    
  std::cout << "bitmask <4> = " << d << std::endl;
}
结果:

bitmask <0> = 0
bitmask <1> = 1
bitmask <2> = 3
bitmask <3> = 7
bitmask <4> = 15