分支未在 Linux 上采用

Branch not taken on Linux

本文关键字:Linux 分支      更新时间:2023-10-16

下面的代码在Windows上按预期工作,但是当使用Clang 6.0构建并在Ubuntu服务器上运行时,它不起作用。CurAnimIndex 是一个 int32,值为 2147483647(max int(。我希望它进入分支,因为增量后的 CurAnimIndex 的值应该是负数,但它不是。

CurAnimIndex++;
if (CurAnimIndex >= AnimSelectorDatas.Num() || CurAnimIndex < 0)
{
CurAnimIndex = 0;
}

0x000000000411a12f  mov    0x0(%r13),%eax 
0x000000000411a133  lea    0x1(%rax),%ecx 
0x000000000411a136  movslq 0x10(%r13),%r15 
0x000000000411a13a  xor    %ebp,%ebp 
0x000000000411a13c  cmp    %r15d,%ecx 
0x000000000411a13f  cmovge %ebp,%ecx 
0x000000000411a142  cmp    $0xffffffff,%eax 
0x000000000411a145  cmovl  %ebp,%ecx 
0x000000000411a148  mov    %ecx,0x0(%r13) 
0x000000000411a14c  mov    0x8(%r13),%r12 enter code here
CurAnimIndex++

CurAnimIndex 是一个 int32,值为 2147483647(max int(。我希望它进入分支,因为增量后 CurAnimIndex 的值应该是负数

2147483647是一个正数。为什么你期望增加一个正数会产生一个负数?这在正常的算术中不会发生。编译器知道这一点,并根据这些知识进行优化。如果CurAnimIndex的初始值已被证明至少为 -1,则检查CurAnimIndex < 0始终已知为假,可以优化掉。

也许您的期望与操作溢出最大可表示值的事实有关。这种期望是错误的,因为签名溢出不能保证具有这种行为。事实上,签名溢出并不能保证具有任何特定行为。程序的行为是未定义的。

执行此操作的正确方法是首先检查该数字是否等于最大可表示值,如果不是,则仅递增。