我只是想知道是否有一些方便的方法来检测在运行时期间C ++程序中使用的任何默认数据类型的任何变量是否发生溢出?方便的是,我的意思是,如果每个变量的值都在其数据类型的范围内,则无需编写代码来跟踪每个变量。或者如果不可能实现这一点,你会怎么做?
例如,
float f1=FLT_MAX+1;
cout << f1 << endl;
在使用“gcc -W -Wall”进行编译或运行时不会出现任何错误或警告。
谢谢和问候!
答案 0 :(得分:6)
考虑使用boosts numeric conversion,这会为您提供negative_overflow
和positive_overflow
例外(examples)。
答案 1 :(得分:4)
在符合IEEE-754标准的系统中,您的示例实际上并未在默认浮点环境中溢出。
在这样的系统中,float是32位二进制浮点,FLT_MAX是C99十六进制浮点表示法中的0x1.fffffep127。将其写成十六进制的整数,它看起来像这样:
0xffffff00000000000000000000000000
添加一个(没有舍入,就像值是任意精度整数一样),给出:
0xffffff00000000000000000000000001
但是在IEEE-754兼容系统的默认浮点环境中,
之间的任何值0xfffffe80000000000000000000000000
和
0xffffff80000000000000000000000000
(包括您指定的值)舍入为FLT_MAX。没有溢出。
复合这个问题,您的表达式(FLT_MAX + 1)很可能在编译时评估,而不是运行时,因为它没有对您的程序可见的副作用。
答案 2 :(得分:2)
在我需要检测溢出的情况下,我使用SafeInt<T>
。这是一个跨平台的解决方案,可以在溢出情况下抛出异常。
SafeInt<float> f1 = FLT_MAX;
f1 += 1; // throws
可在codeplex上使用
答案 3 :(得分:2)
在我开发C ++(199x)的过去,我们使用了一种名为Purify的工具。那时它是一个工具,用于检测目标代码并在测试运行期间记录所有“坏”。 我做了一个快速的谷歌,我不太确定它是否仍然存在。
据我所知,现在有几种开源工具或多或少都相同。 结帐电子设备和valgrind。
答案 4 :(得分:1)
可能对此主题有用的信息:
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/archive/2006/02/02/523392.aspx
答案 5 :(得分:0)
Clang提供-fsanitize=signed-integer-overflow
和-fsanitize=unsigned-integer-overflow
。
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation