4

我只是想知道是否有一些方便的方法来检测在运行期间 C++ 程序中使用的任何默认数据类型的任何变量是否发生溢出?方便,我的意思是不需要编写代码来跟踪每个变量,如果它在其数据类型的范围内,每次它的值发生变化。或者如果不可能实现这一点,你会怎么做?

例如,

float f1=FLT_MAX+1;
cout << f1 << endl;

在使用“gcc -W -Wall”编译或运行时不会给出任何错误或警告。

谢谢并恭祝安康!

4

5 回答 5

6

考虑使用boosts 数字转换,它会给你negative_overflowpositive_overflow例外(例子)。

于 2009-09-22T14:26:59.467 回答
4

您的示例实际上不会在符合 IEEE-754 的系统中的默认浮点环境中溢出。

在这样的系统上,float 是 32 位二进制浮点,FLT_MAX 是 C99 十六进制浮点表示法中的 0x1.fffffep127。将其写为十六进制整数,如下所示:

0xffffff00000000000000000000000000

加一(没有四舍五入,好像这些值是任意精度整数),给出:

0xffffff00000000000000000000000001

但是在符合 IEEE-754 的系统上的默认浮点环境中,之间的任何值

0xfffffe80000000000000000000000000

0xffffff80000000000000000000000000

(包括您指定的值)四舍五入到 FLT_MAX。不会发生溢出。

更复杂的是,您的表达式 (FLT_MAX + 1) 可能会在编译时而不是运行时进行评估,因为它对您的程序没有可见的副作用。

于 2009-09-22T14:29:54.180 回答
3

在需要检测溢出的情况下,我使用SafeInt<T>. 这是一个跨平台解决方案,在溢出情况下会引发异常。

SafeInt<float> f1 = FLT_MAX;
f1 += 1; // throws

它在 codeplex 上可用

于 2009-09-22T14:25:16.767 回答
2

回到过去,当我开发 C++ (199x) 时,我们使用了一个名为 Purify 的工具。那时它是一个工具,可以检测目标代码并在测试运行期间记录所有“坏”的东西。我做了一个快速的谷歌,我不太确定它是否仍然存在。

据我所知,现在存在一些或多或少相同的开源工具。结帐 Electricfence 和 valgrind。

于 2009-09-22T15:02:25.917 回答
0

Clang 提供-fsanitize=signed-integer-overflow-fsanitize=unsigned-integer-overflow.

http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation

于 2014-11-29T15:37:20.447 回答