是否有 g++ 警告或其他工具可以识别整数除法(截断为零)?我有数千行代码的计算不可避免地会出现数字错误,通常是由于需要定位的“float = int/int”。我需要一个合理的方法来找到这些。
6 回答
试试-Wconversion
。
从 gcc 的手册页:
警告可能改变值的隐式转换。这包括实数和整数之间的转换,如“x”为“double”时的“abs (x)”;有符号和无符号之间的转换,例如“unsigned ui = -1”;并转换为更小的类型,例如“sqrtf (M_PI)”。不要警告像“abs ((int) x)”和“ui = (unsigned) -1”这样的显式转换,或者如果值没有被“abs (2.0)”中的转换改变。可以使用 -Wno-sign-conversion 禁用有关有符号和无符号整数之间转换的警告。
对于 C++,还警告“NULL”和非指针类型之间的转换;混淆用户定义转换的重载解决方案;以及永远不会使用类型转换运算符的转换:转换为“void”、相同类型、基类或对它们的引用。在 C++ 中默认禁用有关有符号和无符号整数之间转换的警告,除非显式启用 -Wsign-conversion。
对于以下示例程序 ( test.cpp
),我收到错误test.cpp: In function ‘int main()’:
test.cpp:7: warning: conversion to ‘float’ from ‘int’ may alter its value
。
#include <iostream>
int main()
{
int a = 2;
int b = 3;
float f = a / b;
std::cout << f;
return 0;
}
我很难称这些数字错误。您要求进行整数计算,并获得了正确的整数计算数字。如果这些数字不可接受,则要求进行浮点计算:
int x = 3;
int y = 10;
int z = x / y;
// "1." is the same thing as "1.0", you may want to read up on
// "the usual arithmetic conversions." You could add some
// parentheses here, but they aren't needed for this specific
// statement.
double zz = 1. * x / y;
关于gcc-Wconversion
的评论:
将浮点变量的类型从更改float
为double
使警告消失:
$ cat 'file.cpp'
#include <iostream>
int main()
{
int a = 2;
int b = 3;
double f = a / b;
std::cout << f;
}
编译$ g++-4.7 -Wconversion 'file.cpp'
不返回任何警告(如$ clang++ -Weverything 'file.cpp'
)。
解释:
由于完全有效的整数算术,不会返回使用该类型时的警告float
,而是因为float
无法存储所有可能的值int
(较大的值不能被float
但被捕获double
)。因此,f
在浮点数的情况下分配 RHS 时,值可能会发生变化,而在双精度数的情况下则不会。说清楚:警告不是因为int/int
assignment 而返回的float = int
。
为此,请参阅以下问题:在 java 中大小相同时浮点和整数数据类型有什么区别,将整数存储为浮点数和舍入以用于 int -> float -> int 往返转换
但是,何时使用float
-Wconversion
仍可用于识别可能受到影响但不全面且实际上并非用于此目的的可能行。出于-Wconversion
查看docs/gcc/Warning-Options.html和此处gcc.gnu.org/wiki/NewWconversion的目的
可能感兴趣的还有以下讨论'隐式转换整数计算以在 C++ 中浮动'
找到此类错误的最佳方法是进行非常好的单元测试。所有替代方案都不够好。