如何检查在C符号整数溢出没有未定义的行为?

问题描述 投票:26回答:3

有(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 integer-overflow
3个回答
60
投票

整数溢出是(注意,在无符号整数运算永远不会溢出,它们被定义为环绕式代替)的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;
}

6
投票

你真的可以只检查与qazxsw POI整数运算溢出:

unsigned

溢出的有符号整数,则行为未定义在C,但在大多数机器上,你可以使用

unsigned a,b,c;
a = b + c;
if (a < b) {
    /* overflow */
}

这会不会对使用任何类型的饱和算法的计算机上工作


-5
投票

你只需要检查他们中的一个。如果X + Y溢出,这将是小于x和y。因此:

int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
    /* overflow */
}

应该足够了。

下面的网站有大量的关于整数溢出的东西:

int sum = x + y; if (sum < x) error;

如果你想处理负数,它可以扩展:

http://www.fefe.de/intof.html
© www.soinside.com 2019 - 2024. All rights reserved.