(1):
// assume x,y are non-negative
if(x > max - y) error;
(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
どちらが好ましいか、またはより良い方法があります。
整数オーバーフローは、Cの「未定義の動作」の標準的な例です(符号なし整数の演算はオーバーフローしないため、代わりにラップアラウンドに定義されていることに注意してください)。これは、x + y
を実行した後、オーバーフローした場合は、すでにホースがかかっていることを意味します。チェックを行うには遅すぎます-プログラムはすでにクラッシュしている可能性があります。ゼロによる除算をチェックするようなものだと考えてください。除算が実行されてからチェックするまで待つと、もう手遅れになります。
したがって、これは、方法(1)が唯一の正しい方法であることを意味します。 max
には、INT_MAX
の<limits.h>
を使用できます。
x
および/またはy
が負になる可能性がある場合は、より困難です。テスト自体がオーバーフローを引き起こさないようにテストを行う必要があります。
if ((y > 0 && x > INT_MAX - y) ||
(y < 0 && x < INT_MIN - y))
{
/* Oh no, overflow */
}
else
{
sum = x + y;
}
オーバーフローをチェックできるのは、unsigned
整数と算術演算のみです。
unsigned a,b,c;
a = b + c;
if (a < b) {
/* overflow */
}
符号付き整数でのオーバーフローの動作はCでは未定義ですが、ほとんどのマシンで使用できます
int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
/* overflow */
}
これは、あらゆる種類の飽和演算を使用するマシンでは機能しません。