Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-03

Assignment on exception (was Re: exception handling in constructor)

9 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang

Hi,

Could anyone explain this:

Number := 123;
try
  Number := Ln(0);
except
end;
WriteLn(Number);

The output is *Nan*, not 123. i.e. when exception occurs the variable is modified anyway! So in the example below assigning MyInstance to nil before Create does not help to ensure it is nil if an exception occurs?

Thanks.

2013/3/2 Hans-Peter Diettrich

Show quoted text 47 lines
Sven Barth schrieb: If you want to ensure that MyInstance is Nil you need to do it like this: > > === code begin === > > try > MyInstance := TMyClass.Create('**AnNonExistentFile'); > except > MyInstance := Nil; > end; > > === code end === > When an exception occurs in Create, the assignment will never take place. That's why MyInstance should be set to Nil *before* calling the constructor. This also applies to memory leak protection of multiple temporary objects: inst1 := nil; inst2 := nil; ... try inst1 := T1.Create; inst2 := T2.Create; ... finally inst1.Free; inst2.Free; ... end; The Free does no harm, even if the instances never were created, when the variables are nil'ed before the try block. DoDi -- ______________________________**_________________ Lazarus mailing list .**freepascal.org http://lists.lazarus.**freepascal.org/mailman/**listinfo/lazarus<http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130302/bad6a56a/attachment-0001.html>

Reply by email

Michael Van Canneyt
to Xiangrong Fang
Xiangrong Fang wrote 13 lines
Hi, Could anyone explain this: Number := 123; try ? Number := Ln(0); except end; WriteLn(Number); The output is Nan, not 123. i.e. when exception occurs the variable is modified anyway!? So in the example below assigning MyInstance to nil before Create does not help to ensure it is nil if an exception occurs?

It does, you can test that.

I suspect that the case above is an artifact of the FPU error reporting, and it should be filed as a bug.

Michael.

Reply by email

Xiangrong Fang
to Michael Van Canneyt
I guess there is really a bug, see the following:
==============================
  f := 123;
  try
    f := ln(0);
  except
  end;
  //WriteLn(f);
  //{
  if f = 123 then
    WriteLn('f=123, not modified')
  else
    WriteLn('f is modified to:', f);
  //}
===============================

If I just WriteLn(f), it output Nan, I think there is some magic happening here.

If I try to use if-then on f, then I get:

An unhandled exception occurred at $000000000040028C : EDivByZero : Division by zero
$000000000040028C line 18 of project1.lpr

2013/3/2 Michael Van Canneyt

Show quoted text 34 lines
On Sat, 2 Mar 2013, Xiangrong Fang wrote: Hi, > > Could anyone explain this: > > Number := 123; > try > Number := Ln(0); > except > end; > WriteLn(Number); > > The output is Nan, not 123. i.e. when exception occurs the variable is > modified anyway! So in the example below assigning MyInstance > to nil before Create does not help to ensure it is nil if an exception > occurs? > It does, you can test that. I suspect that the case above is an artifact of the FPU error reporting, and it should be filed as a bug. Michael. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130302/cca7fbdb/attachment.html>

Reply by email

Sven Barth
to Xiangrong Fang: Could anyone explain this: Number := 123; try Number := Ln(0); except end;…
Xiangrong Fang wrote 14 lines
Hi, Could anyone explain this: Number := 123; try Number := Ln(0); except end; WriteLn(Number); The output is *Nan*, not 123. i.e. when exception occurs the variable is modified anyway! So in the example below assigning MyInstance to nil before Create does not help to ensure it is nil if an exception occurs?

Because there is no exception. If you put a "Writeln" or something into the except block you'll see that no exception is raised. Additionally the "ln" is a compiler intrinsic. And as you give it a constant 0 the compiler will hardcode the "NaN" value instead of calculating it.

The safest way in this case is to put the "Number := 123" into the "except" block (though in this specific example it wouldn't change anything).

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 20 lines
On 02.03.2013 14:04, Xiangrong Fang wrote: > Hi, > > Could anyone explain this: > > Number := 123; > try > Number := Ln(0); > except > end; > WriteLn(Number); > > The output is *Nan*, not 123. i.e. when exception occurs the variable is > modified anyway! So in the example below assigning MyInstance to nil > before Create does not help to ensure it is nil if an exception occurs? Because there is no exception. If you put a "Writeln" or something into the except block you'll see that no exception is raised. Additionally the "ln" is a compiler intrinsic. And as you give it a constant 0 the compiler will hardcode the "NaN" value instead of calculating it.

Hah, I had not thought of this. Indeed, assembler shows you are right :-)

Michael.

Reply by email

waldo kitty
to Xiangrong Fang: I guess there is really a bug, see the following: ============================== f := 123;
Xiangrong Fang wrote 23 lines
I guess there is really a bug, see the following: ============================== f := 123; try f := ln(0); except end; //WriteLn(f); //{ if f = 123 then WriteLn('f=123, not modified') else WriteLn('f is modified to:', f); //} =============================== If I just WriteLn(f), it output Nan, I think there is some magic happening here. If I try to use if-then on f, then I get: An unhandled exception occurred at $000000000040028C : EDivByZero : Division by zero $000000000040028C line 18 of project1.lpr

i am unable to reproduce this...

Lazarus 1.1 r39940 FPC 2.6.0 i386-win32-win32/win64

i started a new Simple Program project and pasted your above code into it...

C:\Documents and Settings\nil>LOCALS~1\Temp\project1 f=123, not modified

program Project1;
var
   f : extended;
begin
   f := 123;
     try
       f := ln(0);
     except
     end;
     //WriteLn(f);
     //{
     if f = 123 then
       WriteLn('f=123, not modified')
     else
       WriteLn('f is modified to:', f);
     //}
end.

so i started a new Program project and again...

C:\Documents and Settings\nil>LOCALS~1\Temp\project1 f=123, not modified

program Project1;
{$mode objfpc}{$H+}
uses
   {$IFDEF UNIX}{$IFDEF UseCThreads}
   cthreads,
   {$ENDIF}{$ENDIF}
   Classes
   { you can add units after this };
var
   f : extended;
begin
   f := 123;
     try
       f := ln(0);
     except
     end;
     //WriteLn(f);
     //{
     if f = 123 then
       WriteLn('f=123, not modified')
     else
       WriteLn('f is modified to:', f);
     //}
end.

what am i missing??

Reply by email

patspiper
to waldo kitty
waldo kitty wrote 96 lines
On 3/2/2013 08:25, Xiangrong Fang wrote: > I guess there is really a bug, see the following: > ============================== > f := 123; > try > f := ln(0); > except > end; > //WriteLn(f); > //{ > if f = 123 then > WriteLn('f=123, not modified') > else > WriteLn('f is modified to:', f); > //} > =============================== > > If I just WriteLn(f), it output Nan, I think there is some magic > happening here. > > If I try to use if-then on f, then I get: > > An unhandled exception occurred at $000000000040028C : > EDivByZero : Division by zero > $000000000040028C line 18 of project1.lpr i am unable to reproduce this... Lazarus 1.1 r39940 FPC 2.6.0 i386-win32-win32/win64 i started a new Simple Program project and pasted your above code into it... C:\Documents and Settings\nil>LOCALS~1\Temp\project1 f=123, not modified program Project1; var f : extended; begin f := 123; try f := ln(0); except end; //WriteLn(f); //{ if f = 123 then WriteLn('f=123, not modified') else WriteLn('f is modified to:', f); //} end. so i started a new Program project and again... C:\Documents and Settings\nil>LOCALS~1\Temp\project1 f=123, not modified program Project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this }; var f : extended; begin f := 123; try f := ln(0); except end; //WriteLn(f); //{ if f = 123 then WriteLn('f=123, not modified') else WriteLn('f is modified to:', f); //} end. what am i missing??

Probably
http://wiki.freepascal.org/Multiplatform_Programming_Guide#Gtk2_and_masking_FPU_exceptions

Stephano

Reply by email

waldo kitty
to waldo kitty
waldo kitty wrote 12 lines
On 3/2/2013 12:43, patspiper wrote: > On 02/03/13 19:34, waldo kitty wrote: >> what am i missing?? > Probably > http://wiki.freepascal.org/Multiplatform_Programming_Guide#Gtk2_and_masking_FPU_exceptions > the main thing i see there is that the sample uses the math unit... if this is what is necessary, then there is definitely some information missing from the problem description ;) i shall test again by adding the math unit to those two test projects...

never mind... my eyes were glazed and i didn't catch the widgetset reference to GTK2... after i had hit send on my previous, it struck me what you were actually pointing to and i had a much closer read... definitely some info missing from the original report :?

Reply by email