boost::integer_mask gcc 编译器错误

Posted

技术标签:

【中文标题】boost::integer_mask gcc 编译器错误【英文标题】:boost::integer_mask gcc compiler error 【发布时间】:2016-10-27 18:41:52 【问题描述】:

我无法编译以下代码(使用 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;

在叮当声上它编译得很好。 使用 g++(版本 6.2.1)我得到 ​​p>

 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 还是 boost 错误?

【问题讨论】:

【参考方案1】:

让我们分析~(least( 0u )) &lt;&lt; Bits 表达式。为什么会变成-1?首先,least 类型将是可以容纳所需位数 (1) 的最小类型。这将是unsigned char,因此表达式现在看起来像~(unsigned char( 0u )) &lt;&lt; Bits~ 运营商将执行积分促销。这导致unsigned char 被提升为int(有符号),因为该类型是可以将无符号字符提升到的类型列表中的第一个,并且它将保存所有可能的值。当在使用二进制补码的系统中解释为有符号整数时,0 的二进制补码为 -1。负整数的左移是未定义的行为,这就是您看到错误的原因。

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

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

【讨论】:

其实用sig_bits_fast编译还是不行,报同样的错误。 @Dreamcooled 我推测,基于查看标题。我已更新我的答案以消除错误的猜测。 我认为您的回答正确地描述了问题的根源:n 【参考方案2】:

我不认为你做错了什么。这显然是编译器错误。 我使用在线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

【讨论】:

再想一想:我认为这不是编译器错误,而另一个答案正确地确定了问题的根源:整数促销。

以上是关于boost::integer_mask gcc 编译器错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥 gcc 将 _mm256_permute2f128_ps 编译为 Vinsertf128 指令?

#ifdef 标志来区分 gcc 和 g++ 编译器? [复制]

如何将javascript代码编译为c++或java

如何在ubuntu16.04创建12.04 gcc编译环境

gcc基本功能以及常见编译选项

gcc