2010-04-13 39 views
20

可能重复:
Best way to detect integer overflow in C/C++如何检查C中的整数溢出?

还有的(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; 

伟驰是prefe或者有更好的方法。

+0

其实重复的是不重复的话,那是在谈论'已明确概括语义unsigned',而溢出带符号的整数是C. – 2015-03-16 15:33:40

+2

不确定的行为没有必要同时检查'sum 2015-10-07 13:43:36

回答

-5

您只需检查其中一个。如果x + y溢出,它将小于x和y。因此:

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

应该足够。

以下网站有一个约整数溢出一堆东西:

http://www.fefe.de/intof.html

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

int sum = x + y; 
if (y >= 0) { 
    if (sum < x) error; 
} else { 
    if (sum > x) error; 
} 
+1

如果'y'为负值怎么办? – 2010-04-13 22:39:23

+1

原始海报指定了非负整数,但我添加了处理负数的代码。 – clahey 2010-04-13 22:40:50

+18

这是不正确的 - 一旦'x + y'溢出,程序就有未定义的行为。您*有*要在您实际执行溢出操作之前进行检查 - 就像您对零除以整数除法一样。 – caf 2010-04-13 23:28:32

6

你可真只检查与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 */ 
} 

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

+4

用带符号整数的事实检查溢出是不正确的。这是未定义的行为,因此编译器会愉快地优化出支票而不用像'-fwrapv'这样的开关来启用签名包装作为语言扩展。这不仅仅是跨体系结构的可移植性问题。 – strcat 2015-09-08 21:24:30

+1

也可以检查签名整数的溢出。见https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow – sbhatla 2016-11-30 15:28:51

47

整数溢出是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; 
} 
+5

如果你是要冷静下来,对于解释你觉得没有帮助或错误的地方留下评论是有礼貌的。 – caf 2011-08-30 03:16:36

+0

顺便说一下,您可以评论此解决方案的性能与其他替代解决方案相比吗? – Pacerier 2013-09-22 18:10:06

+6

将性能与不正确的解决方案进行比较是没有意义的。你有什么其他正确的解决方案? – caf 2013-09-23 01:04:32