我只是想知道是否有一些方便的方法来检测在运行期间 C++ 程序中使用的任何默认数据类型的任何变量是否发生溢出?方便,我的意思是不需要编写代码来跟踪每个变量,如果它在其数据类型的范围内,每次它的值发生变化。或者如果不可能实现这一点,你会怎么做?
例如,
float f1=FLT_MAX+1;
cout << f1 << endl;
在使用“gcc -W -Wall”编译或运行时不会给出任何错误或警告。
谢谢并恭祝安康!
考虑使用boosts 数字转换,它会给你negative_overflow
和positive_overflow
例外(例子)。
您的示例实际上不会在符合 IEEE-754 的系统中的默认浮点环境中溢出。
在这样的系统上,float 是 32 位二进制浮点,FLT_MAX 是 C99 十六进制浮点表示法中的 0x1.fffffep127。将其写为十六进制整数,如下所示:
0xffffff00000000000000000000000000
加一(没有四舍五入,好像这些值是任意精度整数),给出:
0xffffff00000000000000000000000001
但是在符合 IEEE-754 的系统上的默认浮点环境中,之间的任何值
0xfffffe80000000000000000000000000
和
0xffffff80000000000000000000000000
(包括您指定的值)四舍五入到 FLT_MAX。不会发生溢出。
更复杂的是,您的表达式 (FLT_MAX + 1) 可能会在编译时而不是运行时进行评估,因为它对您的程序没有可见的副作用。
在需要检测溢出的情况下,我使用SafeInt<T>
. 这是一个跨平台解决方案,在溢出情况下会引发异常。
SafeInt<float> f1 = FLT_MAX;
f1 += 1; // throws
它在 codeplex 上可用
回到过去,当我开发 C++ (199x) 时,我们使用了一个名为 Purify 的工具。那时它是一个工具,可以检测目标代码并在测试运行期间记录所有“坏”的东西。我做了一个快速的谷歌,我不太确定它是否仍然存在。
据我所知,现在存在一些或多或少相同的开源工具。结帐 Electricfence 和 valgrind。
Clang 提供-fsanitize=signed-integer-overflow
和-fsanitize=unsigned-integer-overflow
.
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation