7

Is there a g++ warning or other tool that can identify integer division (truncation toward zero)? I have thousands of lines of code with calculations that inevitably will have numerical errors typically due to "float = int/int" that need to be located. I need a reasonable method for finding these.

user763322
  • 71
  • 2
  • 1
    Are there any OS restrictions? (for static analysis tool recommendations). –  May 20 '11 at 19:54
  • Currently using Debian 5.06 and likely 6.01 in the near future. – user763322 May 20 '11 at 20:08
  • I use gcc and I wasn't able to find any warning that will catch this ` double alpha = 4/9/M_PI;`. I tried `-Wall`, `-Wextra` and `-Wconversion`. Expressions involving floats and integer division should give warning in my opinion. – alfC Jan 08 '18 at 03:19

6 Answers6

2

Try -Wconversion.

From gcc's man page:

Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like "abs (x)" when "x" is "double"; conversions between signed and unsigned, like "unsigned ui = -1"; and conversions to smaller types, like "sqrtf (M_PI)". Do not warn for explicit casts like "abs ((int) x)" and "ui = (unsigned) -1", or if the value is not changed by the conversion like in "abs (2.0)". Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion.

For C++, also warn for conversions between "NULL" and non-pointer types; confusing overload resolution for user-defined conversions; and conversions that will never use a type conversion operator: conversions to "void", the same type, a base class or a reference to them. Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.

For the following sample program (test.cpp), I get the error 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;
}
Chris Frederick
  • 5,482
  • 3
  • 36
  • 44
  • I've tried this warning before, but unfortunately there are so many implicit conversions in the code that it isn't feasible to pick out the ones related to integer division. I need to address the numerical errors prior to doing any kind of code cleanup that would allow Wconversion to be useful in this case. – user763322 May 20 '11 at 20:15
  • If you have that many conversion errors, why don't you just pipe them through `grep` and filter on `float`? – Chris Frederick May 21 '11 at 04:54
2

I have a hard time calling these numerical errors. You asked for integer calculations, and got the correct numbers for integer calculations. If those numbers aren't acceptable, then ask for floating point calculations:

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;
Max Lybbert
  • 19,717
  • 4
  • 46
  • 69
1

Remark on -Wconversion of gcc:

Changing the type of the floating point variable from float to double makes the warning vanish:

$ cat 'file.cpp'

#include <iostream>

int main()
{
   int a = 2;
   int b = 3;
   double f = a / b;

   std::cout << f;
}

Compiling with $ g++-4.7 -Wconversion 'file.cpp' returns no warnings (as $ clang++ -Weverything 'file.cpp').

Explanation:

The warning when using the type float is not returned because of the totally valid integer arithmetics, but because float cannot store all possible values of int (larger ones cannot be captured by float but by double). So there might be a change of value when assigning RHS to f in the case of float but not in the case of double. To make it clear: The warning is not returned because of int/int but because of the assignment float = int.

For this see following questions: what the difference between the float and integer data type when the size is same in java, Storing ints as floats and Rounding to use for int -> float -> int round trip conversion

However, when using float -Wconversion could still be useful to identify possible lines which are affected but is not comprehensive and is actually not intended for that. For the purpose of -Wconversion see docs/gcc/Warning-Options.html and here gcc.gnu.org/wiki/NewWconversion

Possibly of interest is also following discussion 'Implicit casting Integer calculation to float in C++'

Community
  • 1
  • 1
Hotschke
  • 9,402
  • 6
  • 46
  • 53
1

This page contains info about g++ warnings. If you've already tried -Wall then the only thing left could be the warnings in this link. On second look -Wconversion might do the trick.

Note: Completely edited the response.

Chris A.
  • 6,817
  • 2
  • 25
  • 43
  • 2
    Overloading an operator involving only primitive types is illegal; i.e., the overload must involve at least one UDT. – ildjarn May 20 '11 at 19:53
0

Have a look at this clang-tidy detection.

It catches cases like this:

d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);
Jan Rüegg
  • 9,587
  • 8
  • 63
  • 105
0

The best way to find such error is to have really good unit tests. All alternatives are not good enough.

BЈовић
  • 62,405
  • 41
  • 173
  • 273