c++ - 在 Linux 上未采用分支
问题描述
下面的代码在 Windows 上按预期工作,但是当使用 Clang 6.0 构建并在 Ubuntu 服务器上运行时,它不起作用。CurAnimIndex 是一个 int32 值,值为 2147483647(最大 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(最大 int)。我希望它进入分支,因为增量后 CurAnimIndex 的值应该是负数
2147483647 是一个正数。为什么你会期望增加一个正数会产生一个负数?这在普通算术中不会发生。编译器知道这一点并根据该知识进行优化。如果已证明 的初始值CurAnimIndex
至少为 -1,则该检查CurAnimIndex < 0
始终为假,并且可以优化掉。
也许您的期望与操作溢出最大可表示值的事实有关。这种期望是错误的,因为不能保证签名溢出具有这种行为。事实上,签名溢出不能保证有任何特定的行为。程序的行为是未定义的。
这样做的正确方法是首先检查数字是否等于最大可表示值,如果不等于则仅增加。
推荐阅读
- java - 有没有办法在 TestNG 中设置全局参数?
- mysql - MySQL 语句 ON DUPLICATE KEY 用于非键
- python - 你如何让 python 库“urwid”的按钮看起来很漂亮?
- python - 如何解决 ReverseNoMatch 错误 django?
- javascript - 如何授权用纯 Javascript 编写的网络应用程序与 Google AutoML 预测模型 Restful API 对话?
- php - 使用 Count 给出错误的行数
- javascript - 将对象数组推送到数组以进行排序
- android - 获取具有非固定键的对象的属性
- docker - 使用 Docker Compose 或 Kubernetes 时动态服务发现如何工作?
- c# - 在 UWP 的 DriveInfo 中访问 AvailableFreeSpace/TotalSize 时出错