表达式中出现意外的整数溢出

时间:2019-06-25 18:56:30

标签: c++ bit-manipulation constexpr bitmask

我正在尝试获得一个unsigned,该位置将完全用1填充(二进制表示形式是32个。我尝试使用以下方法:

constexpr unsigned all_ones = (((1 << 31) - 1) << 1) | 1;

但是在编译时(在Ubuntu上为g ++),会出现以下错误:

error: overflow in constant expression [-fpermissive]

是什么导致此错误?对我来说,表情看起来不错,就像在这里拆除的一样:

1       = 000...001
  << 31 = 100...000
  - 1   = 011...111
  << 1  = 111...110
  | 1   = 111...111

我知道我可以通过其他方式(例如〜0u)来获得所需的值,但是我要问的是为什么这种方法不起作用。

2 个答案:

答案 0 :(得分:6)

您的表达式使用有符号整数常量,并且确实溢出到符号位中(这使您陷入未定义的行为)。您可以通过指定无符号常量来避免该错误:

constexpr unsigned all_ones = (((1U << 31) - 1) << 1) | 1;

但是表达式仍然过于复杂,可以更好地表示为:

constexpr unsigned all_ones = ~0U;

答案 1 :(得分:3)

我会尝试使用标头climits中的定义,这就是它们的用途,您基本上是在要求可以代表无符号整数的最大值。

constexpr无符号all_ones = UINT_MAX;

参见此处:http://www.cplusplus.com/reference/climits/