Detecting inadvertent use of integer division

Walter Bright newshound1 at digitalmars.com
Mon Dec 14 02:17:34 PST 2009


Don wrote:
> Consider this notorious piece of code:
> 
> assert(x>1);
> double y = 1 / x;
> 
> This calculates y as the reciprocal of x, if x is a floating-point 
> number. But if x is an integer, an integer division is performed instead 
> of a floating-point one, and y will be 0.
> 
> It's a very common newbie trap, but I find it still catches me 
> occasionally, especially when dividing two variables or compile-time 
> constants.
> 
> In the opPow thread there were a couple of mentions of inadvertent 
> integer division, and how Python is removing this error by making / 
> always mean floating-point division, and introducing a new operator for 
> integer division.
> 
> We could largely eliminate this type of bug without doing anything so 
> drastic. Most of the problem just comes from C's cavalier attitude to 
> implicit casting. All we'd need to do is tighten the implicit conversion 
> rules for int->float, in the same way that the int->uint rules have been 
> tightened:
> 
> "If an integer expression has an inexact result (ie, involves an inexact 
> integer divison), that expression cannot be implicitly cast to a 
> floating-point type."

But the compiler cannot reliably tell if it will produce an inexact result.


> (This means that double y = int_val / 1;  is OK, and also:
>  double z = 90/3; would be OK. An alternative rule would be:
> "If an integer expression involves integer divison, that expression 
> cannot be implicitly cast to a floating-point type").

This is kinda complicated if one has, say:

     double z = x/y + 3;


> In the very rare cases where the result of an integer division was 
> actually intended to be stored in a float, an explicit cast would be 
> required. So you'd write:
> double y = cast(int)(1/x);
> 
> Like the implicit uint->int casts which have recently been disallowed, I 
> think this would prevent a lot of bugs, without causing much pain.

Maybe it's easier to simply disallow 1/x, where x is an int, and the 
numerator is '1'. But then maybe that will cause problems with generic 
code. I don't think there's an easy answer here.



More information about the Digitalmars-d mailing list