奇怪的 LLVM 在 For 循环中无符号到有符号的转换
Weird LLVM Unsigned to Signed Conversion in For Loop
我不确定这是否只发生在Apple的LLVM Compiler 4.0(XCode 4.4.1)上,但我注意到以下行为:
NSUInteger currentIndex = 0;
NSUInteger sideSize = 2;
// Method A
for (NSInteger i = currentIndex-sideSize; i < currentIndex+sideSize; i++)
{
printf("In the loopn"); // WON'T be executed
}
// Method B
for (NSInteger i = (NSInteger)(currentIndex-sideSize); i < currentIndex+sideSize; i++)
{
printf("In the loopn"); // WON'T be executed
}
// Method C
for (NSInteger i = (NSInteger)(currentIndex-sideSize); i < (NSInteger)(currentIndex+sideSize); i++)
{
printf("In the loopn"); // WILL be executed
}
// Method D
NSInteger initialIndex = currentIndex-sideSize;
NSInteger finalIndex = currentIndex+sideSize;
for (NSInteger i = initialIndex; i < finalIndex; i++)
{
printf("In the loopn"); // WILL be executed
}
方法 B 和方法 C 几乎相同,只是我们没有将加法运算符的结果显式转换为有符号值。
谁能解释一下发生了什么?
问题是,如果在表达式中有有符号和无符号操作数,根据 C 标准,有符号操作数将被提升为无符号整数。然后发生的情况是,如果你从 0 中减去 2,则得到 -2,但由于它被视为无符号整数(在比较值时),它会溢出并最终成为某个大数字。这就是为什么方法 B 中的循环不执行而方法 C 中的循环执行的原因(当您显式将结果和/或操作数强制转换为 signed 时,不会发生溢出,并且循环正确从 -2 变为 2)。
这在C标准中是一件奇怪的事情,而不是在LLVM中。LLVM完全遵循这里的标准。
相关文章:
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 获取隐式转换溢出从无符号到已签名的警告
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 从 std::vector<无符号字符>切片中提取 int?
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- 未定义的符号:符号引用错误.没有输出写入主
- 符号"符号"的偏移不一致
- 未定义的符号 - 符号查找错误