我该如何检测无符号整数溢出?

733

我正在使用C++编写程序,以找到所有满足ab=c的解,其中abc一起使用所有数字0-9,每个数字仅使用一次。该程序循环遍历ab的值,并每次在abab上运行数字计数例程,以检查是否满足数字条件。

然而,当ab超出整数限制时,会生成虚假的解。最终我使用类似以下代码来检查这种情况:

unsigned long b, c, c_test;
...
c_test=c*b;         // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test;      // No overflow

有没有更好的方法来测试溢出?我知道一些芯片在溢出发生时会设置内部标志,但我从未在C或C++中看到它被访问过。


请注意,在C和C++中,带符号int溢出是未定义行为,因此您必须在不实际引起溢出的情况下进行检测。关于加法之前的带符号整数溢出,请参见Detecting signed overflow in C/C++


29
以下是关于这个主题可能有用的信息:Seacord的《C和C++安全编码》第5章 - http://www.informit.com/content/images/0321335724/samplechapter/seacord_ch05.pdf 用于C++的SafeInt类 - http://blogs.msdn.com/david_leblanc/archive/2008/09/30/safeint-3-on-codeplex.aspx - http://www.codeplex.com/SafeInt 用于C的IntSafe库:- [http://blogs.msdn.com/michael_howard/archiv - Michael Burr
3
Seacord的Secure Coding是一个很好的资源,但不要使用IntegerLib。请参阅http://blog.regehr.org/archives/593/。 - jww
44
使用gcc编译器选项-ftrapv将导致在(有符号)整数溢出时生成一个SIGABRT信号。详见此处 - nibot
3
它并没有回答溢出问题,但另一种解决方法是使用类似GMP的BigNum库来保证您始终具有足够的精度。如果您预先分配足够的数字,就不必担心溢出问题。 - wrdieter
1
@HeadGeek在他的回答中提供的信息基本上也是我会说的。但是,还有一个补充。你现在检测乘法溢出的方式可能是最快的。在ARM上,正如我在HeadGeek的回答中评论的那样,您可以使用clz指令或__clz(unsigned)函数来确定数字的等级(其最高位在哪里)。由于我不确定这是否适用于x86或x64,因此我假设它不可用,并且说找到最高有效位将需要最多log(sizeof(int)*8)条指令。 - nonsensickle
显示剩余2条评论
31个回答

-8

内联汇编可以直接检查溢出位。如果你要使用C++,那么你真的应该学习汇编。


44
使用内联汇编会限制代码在某一架构上运行,并可能导致编译器关闭许多优化,因此应尽量避免使用。 - James Curran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接