C++ C++;if语句数学计算错误

C++ C++;if语句数学计算错误,c++,C++,我发现了一个我认为是数学错误的东西,我不完全理解它为什么会发生 if (mNextBottomIndex < mBlocks.size() - 1) { if (mBlocks[mNextBottomIndex + 1]->getGlobalPosition().y >= -mBlocks[mNextBottomIndex + 1]->getHeight()) { mBlocks[mNextBottomIndex + 1]->setAlpha(1.0f)

我发现了一个我认为是数学错误的东西,我不完全理解它为什么会发生

if (mNextBottomIndex < mBlocks.size() - 1) {
  if (mBlocks[mNextBottomIndex + 1]->getGlobalPosition().y >= -mBlocks[mNextBottomIndex + 1]->getHeight()) {
    mBlocks[mNextBottomIndex + 1]->setAlpha(1.0f);
    mNextBottomIndex++;
  }
}
现在它似乎没有崩溃。

mBlocks.size()是一个无符号整型。
如果从值为0的无符号int中减去1,它将下溢为一个大的正数。

您没有向我们显示
mBlocks
的类型,但是考虑到您正在调用of(或一些类似的stdlib容器;例如),返回类型为
size\u type
(来自@cppreference):

std::vector::size

size_type size() const;
始终是无符号整数(来自@cppreference):

成员类型

size\u-type
无符号整数类型(通常
std::size\u-t

当您从
0
中减去
1
时,将生成一个无符号类型的负数(在执行比较之前通过整数转换),该负数(对于这个小幅度的负数
-1
)将环绕成一个大的无符号整数,这将自然地将
mNextBottomIndex<…
谓词作为
true
传递

另请参见以下内容:


您没有向我们显示
mBlocks的类型,但是考虑到您正在调用of(或一些类似的stdlib容器;例如),返回类型为
size\u type
(来自@cppreference):

std::vector::size

size_type size() const;
始终是无符号整数(来自@cppreference):

成员类型

size\u-type
无符号整数类型(通常
std::size\u-t

当您从
0
中减去
1
时,将生成一个无符号类型的负数(在执行比较之前通过整数转换),该负数(对于这个小幅度的负数
-1
)将环绕成一个大的无符号整数,这将自然地将
mNextBottomIndex<…
谓词作为
true
传递

另请参见以下内容:


如果
mBlocks.size()
返回无符号值,
mBlocks.size()-1
,当
mBlocks.size()
返回
0
时,通常会返回一个非常大的数字(其类型的最大数量)。@AlgirdasPreidžius不“通常”,总是。未签名算术被指定为wrap。@Quentin和这条语句总是让我感到困惑,因为下面的引语:如果在表达式求值过程中,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义<代码>-1
不在无符号类型的可表示值的范围内,因此从技术上讲,它应该是未定义的。@AlgirdasPreidžius在被认为不在可表示值的范围内之前,我相信
mBlocks.size()-1
是一个PR值(整数类型),这意味着它可以隐式转换为任何其他整数类型(通过整数转换)。我认为这是一个比表达式计算的一般上下文更为具体的上下文。另一个例子是,使用大多数迂腐的编译器开关可以解决这个问题。如果
mBlocks.size()
返回无符号值,
mBlocks.size()-1
,而
mBlocks.size()
返回
0
,通常会缠绕到一个非常大的数字(其类型的最大数量)。@AlgirdasPreidžius不“通常”,总是。未签名算术被指定为wrap。@Quentin和这条语句总是让我感到困惑,因为下面的引语:如果在表达式求值过程中,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义<代码>-1不在无符号类型的可表示值的范围内,因此从技术上讲,它应该是未定义的。@AlgirdasPreidžius在被认为不在可表示值的范围内之前,我相信
mBlocks.size()-1
是一个PR值(整数类型),这意味着它可以隐式转换为任何其他整数类型(通过整数转换)。我相信这是一个比表达式计算的一般上下文更具体的上下文。另一个例子是,使用大多数迂腐的编译器开关可以解决这个问题。