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

3 c++ bit-manipulation bitmask constexpr

我试图得到一个unsigned完全用1填充的(二进制表示形式是32个。我尝试使用以下方法:

constexpr unsigned all_ones = (((1 << 31) - 1) << 1) | 1;
Run Code Online (Sandbox Code Playgroud)

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

error: overflow in constant expression [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

是什么导致此错误?在我看来,此表达式看起来不错,如下所示:

1       = 000...001
  << 31 = 100...000
  - 1   = 011...111
  << 1  = 111...110
  | 1   = 111...111
Run Code Online (Sandbox Code Playgroud)

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

Bla*_*ace 5

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

constexpr unsigned all_ones = (((1U << 31) - 1) << 1) | 1;
Run Code Online (Sandbox Code Playgroud)

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

constexpr unsigned all_ones = ~0U;
Run Code Online (Sandbox Code Playgroud)

  • @YanB。-溢出表示结果太大而无法适合该类型。移位值以使结果大于类型可以表示的范围是溢出。底层机制可能涉及修改符号位,但这无关紧要。该值太大。 (2认同)