Delphi Berlin 10.1 Division by zero exception missing
Asked Answered
R

2

8

I am surprised not the get division by zero exception. How do I get it back?

Berlin 10.1 very recent install, new project,

procedure TForm1.Button1Click(Sender: TObject);
var
  a: Double;
begin
  a := 5/0;                     // No exception
  ShowMessage(a.ToString);      // -> 'INF'
end;
Reenareenforce answered 2/12, 2017 at 19:23 Comment(6)
Confirmed on my copy of Berlin. Looks like it's in Tokyo too: community.embarcadero.com/answers/…Hyperkinesia
@Jerry: that is because the expression is a constant expression and not calculated at runtime. At least one of the two numbers (dividend, divisor) must be a variable to cause an exception.Expressman
Great! Compiler knows how to divide by 0 :)Farm
@Victoria: actually, the compiler probably leaves it to the FPU too, but does it at compile time and obviously it masks (some) exceptions when doing that. An infinite is a valid result if the zero division exception is masked.Expressman
in Seattle too i can see this conditionCiri
@JerryDodge the link no longer workes since Embarcadero shut down the community site. And unfortunately it isn't on archive.org either.Burned
R
8
a := 5/0;

The expression 5/0 is, in technical language terms, a constant expression.

A constant expression is an expression that the compiler can evaluate without executing the program in which it occurs. Constant expressions include numerals; character strings; true constants; values of enumerated types; the special constants True, False, and nil; and expressions built exclusively from these elements with operators, typecasts, and set constructors.

As such this expression is evaluated by the compiler, and not at runtime. So its evaluation is determined by compile time rules and cannot be influenced by runtime floating point unit exception masks.

And those rules state that positive value divided by zero is equal to +INF, a special IEEE754 value. If you change the expression to have at least one argument that is not a constant expression then it will be evaluated at runtime, and a divide by zero exception will be raised.

Rydder answered 2/12, 2017 at 21:48 Comment(0)
S
6

You can control which floating point exceptions are triggered using the SetExceptionMask function in Math unit: http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Math.SetExceptionMask

To disable all floating point exceptions use:

SetExceptionMask(exAllArithmeticExceptions);

To enable all floating point exception use:

SetExceptionMask([]);

Also note that in your example code the compiler will determine the value at compile time (since the expression is constant) so it will not trigger an exception regardless of the value passed to SetExceptionMask. To trigger exception you need a slightly more complex example, something like this:

program test;
uses Math;
var
  xx,yy: double;
begin
SetExceptionMask([]);
xx := 1;
yy := 0;
halt(round(xx/yy));
end.
Seduction answered 2/12, 2017 at 20:32 Comment(4)
And to only enable a Division by Zero exception, do something like: SetExceptionMask(GetExceptionMask - [exZeroDivide]);.Expressman
At least the first part of this answer has no bearing on the question askedRydder
@DavidHeffernan In a discussion about floating point exception not triggering then I think it is relevant to mention SetExceptionMask. Sure, it might not have been the reason in the OPs code, but often code posted here as been simplified too much and the real code could have used variables.Seduction
@VilleKrumlinde Fair comment, this is a situation where a poster could reasonably have a problem, and manage to formulate a minimal reproducible example that is symptomatically similar, but has a different root cause.Adversative

© 2022 - 2024 — McMap. All rights reserved.