次のコードでは、unsigned char が int より小さいと仮定します。
int f(void)
{
int i = -2;
unsigned char uc = 1;
return (i + uc) < 17;
}
|
前述のコードを使用すると、-xtransition オプションを使用したときに、次の警告が発行されます。
6 行目:警告: ISO C では "<" の意味が変わります。明示的なキャストを使用してください。
加算の結果の型は int (値保持) または unsigned int (符号なし保存) です。しかし、どちらの場合でもビットパターンは同じです。2 の補数を使用するマシンでは、次のようになります。
i: 111...110 (-2)
+ uc: 000...001 ( 1)
===================
111...111 (-1 or UINT_MAX)
|
このビット表現は、int では -1 に対応し、unsigned int では UINT_MAX に対応します。したがって、結果の型が int の場合、符号付き比較が使用され、「より小さいか」の答えは真になります。結果の型が unsigned int の場合、符号なしの比較が行われ、「より小さいか」の答えは偽になります。
キャストの加算を使用すると、2 つの動作のうち、どちらを希望するかを指定できます。
value preserving:
(i + (int)uc) < 17
unsigned preserving:
(i + (unsigned int)uc) < 17
|
コンパイラが異なれば同じコードに対する解釈も異なるため、この式は曖昧になる可能性があります。キャストの加算を使用することにより、コードが読みやすくなると同時に、警告メッセージも発行されなくなります。