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

C++ 表达式中出现意外的整数溢出,c++,bit-manipulation,constexpr,bitmask,C++,Bit Manipulation,Constexpr,Bitmask,我正在尝试获取一个无符号的,它将完全由1填充(以二进制表示为32个1)。我尝试使用以下方法: constexpr unsigned all_ones = (((1 << 31) - 1) << 1) | 1; 是什么导致了这个错误?对我来说,这个表达式看起来不错,如下所示: 1 = 000...001 << 31 = 100...000 - 1 = 011...111 << 1 = 111...110 | 1

我正在尝试获取一个无符号的,它将完全由1填充(以二进制表示为32个1)。我尝试使用以下方法:

constexpr unsigned all_ones = (((1 << 31) - 1) << 1) | 1;
是什么导致了这个错误?对我来说,这个表达式看起来不错,如下所示:

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

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

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

我会尝试使用标题climits中的defines,这就是它们的用途,您基本上要求的是无符号整数可以表示的最大值

constexpr unsigned all_one=UINT_MAX


请参见此处:

有符号整数溢出是一种未定义的行为(与无符号整数溢出不同)。顺便说一句,您可以使用
constepr unsigned int all_one{-1u};
来代替。就我个人而言,如果我想设置所有位,我更喜欢
~0u
constepr unsigned all_one=~0u;
谢谢,我不知道“溢出”进入符号位将被视为溢出。@YanB。这与递增有符号变量直到溢出较低的31位没有什么不同。这种情况下的解决方案是使用无符号类型执行所有操作。@YanB。--溢出意味着结果太大,无法放入类型中。移动值以使结果大于类型可以表示的值ENT是一个溢出。底层机制可能涉及修改符号位,但这不相关。值太大。因为这是C++,所以您也可以使用。
constexpr unsigned all_ones = (((1U << 31) - 1) << 1) | 1;
constexpr unsigned all_ones = ~0U;