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 )) << Bits
表达式。为什么会变成-1?首先,least
类型将是可以容纳所需位数 (1) 的最小类型。这将是unsigned char
,因此表达式现在看起来像~(unsigned char( 0u )) << 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 指令?