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 になります)。 .

これは、LLVM ではなく、C 標準では奇妙なことです。ここでは、LLVM は標準に完全に従っています。

于 2012-08-17T05:32:49.480 に答える