我想知道在C++程序运行时是否有一种方便的方法来检测任何默认数据类型变量是否发生溢出?所谓方便,是指不需要每次值改变时编写代码来跟踪每个变量是否在其数据类型范围内。如果无法实现此操作,您会怎么做?
例如:
例如:
float f1=FLT_MAX+1;
cout << f1 << endl;
在使用"gcc -W -Wall"编译或运行时,都没有任何错误或警告。
谢谢和问候!
float f1=FLT_MAX+1;
cout << f1 << endl;
在使用"gcc -W -Wall"编译或运行时,都没有任何错误或警告。
谢谢和问候!
在符合IEEE-754标准的系统中,默认浮点环境下,您的示例实际上不会溢出。
在这样的系统中,32位二进制浮点数的float类型,FLT_MAX在C99十六进制浮点表示法中为0x1.fffffep127。将其以十六进制整数写出来,如下所示:
0xffffff00000000000000000000000000
添加一个数(不进行四舍五入,就像这些值是任意精度整数一样),得到:
0xffffff00000000000000000000000001
0xfffffe80000000000000000000000000
并且
0xffffff80000000000000000000000000
(包括您指定的值) 被舍入为 FLT_MAX。不会发生溢出。
更加复杂的是,您的表达式 (FLT_MAX + 1) 可能会在编译时而不是运行时进行评估,因为它对您的程序没有可见的副作用。
SafeInt<T>
。它是一个跨平台的解决方案,在发生溢出时会抛出异常。SafeInt<float> f1 = FLT_MAX;
f1 += 1; // throws
它可以在codeplex上获得
SafeInt<float>
无法编译。 - metablaster早些年我在开发C++(199x)时使用过一种叫做Purify的工具。那时候,它是一种仪器化目标代码并在测试运行期间记录所有“不好”的工具。
我快速搜索了一下,但不确定它是否仍然存在。
据我所知,现在有几种开源工具可以做类似的事情。可以试试Electricfence和Valgrind。
Clang提供了-fsanitize=signed-integer-overflow
和-fsanitize=unsigned-integer-overflow
。
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation