0

我不确定这是否只发生在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 loop\n"); // WON'T be executed
}

// Method B
for (NSInteger i = (NSInteger)(currentIndex-sideSize); i < currentIndex+sideSize; i++)
{
    printf("In the loop\n"); // WON'T be executed
}

// Method C
for (NSInteger i = (NSInteger)(currentIndex-sideSize); i < (NSInteger)(currentIndex+sideSize); i++)
{
    printf("In the loop\n"); // WILL be executed
}

// Method D
NSInteger initialIndex = currentIndex-sideSize;
NSInteger finalIndex = currentIndex+sideSize;
for (NSInteger i = initialIndex; i < finalIndex; i++)
{
    printf("In the loop\n"); // WILL be executed
}

方法 B 和方法 C 几乎相同,只是我们没有将加法运算符的结果显式转换为有符号值。

谁能解释发生了什么?

4

1 回答 1

4

问题是,如果在表达式中存在有符号和无符号操作数,根据 C 标准,有符号操作数将被提升为无符号整数。然后发生的情况是,如果从 0 中减去 2,则结果为 -2,但由于它被视为无符号整数(在比较值时),它会溢出并最终成为一个大数。这就是为什么方法 B 中的循环不执行而方法 C 中的循环执行的原因(当您将结果和/或操作数显式转换为有符号时,不会发生溢出并且循环正确地从 -2 变为 2) .

这在 C 标准中是一件奇怪的事情,而不是在 LLVM 中。LLVM 完全遵循这里的标准。

于 2012-08-17T05:32:49.480 回答