Re: [Lazarus] exception handling in constructor

2013-03-02 Thread Sven Barth

On 02.03.2013 03:49, Xiangrong Fang wrote:

Hi there,

If my class constructor looks like this:

constructor TMyClass.Create(fn: string);
begin
   sl := TStringList.Create;
   try
 fs := TFileStream.Create(fn, fmOpenRead);
   except
 self.Destroy;
   end;
end;


No, this is a bad idea. If an exception occurs inside the constructor 
the destructor will be called automatically. I don't even want to think 
about what bad things could happen if you call Destroy inside the 
constructor...



I create the objec like:  MyInstance :=
TMyClass.Create('AnNonExistentFile');  An exception occured, I can
ensure that:

 1. there is no memory leak.


There won't be a memory leak.


 2. the MyInstance variable is assigned *nil*?


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 ===

Regards,
Sven

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling in constructor

2013-03-02 Thread Howard Page-Clark

On 02/03/13 10:51, Michael Van Canneyt wrote:


This will definitely cause a memory leak, because the FPC code does not
know that an exception occurred in the constructor (you catch it with
Except), and hence will not call the destructor.


Thanks for the correction and explanation.

Howard


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling in constructor

2013-03-02 Thread Hans-Peter Diettrich

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
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling in constructor

2013-03-02 Thread Flávio Etrusco
On Sat, Mar 2, 2013 at 7:51 AM, Michael Van Canneyt
mich...@freepascal.org wrote:


 On Sat, 2 Mar 2013, Howard Page-Clark wrote:

 On 02/03/13 5:45, Flávio Etrusco wrote:

 On Fri, Mar 1, 2013 at 11:49 PM, Xiangrong Fang xrf...@gmail.com wrote:

(...)

 Also, setting Self to nil is nonsense.

 If you do FreeAndNil(Self) instead, it will work.

 But I would seriously warn against doing this kind of thing.


Wow, this is unexpected. I always thougth that by definition a
constructor would never return nil - so Self was a by-value
parameter, even inside a constructor.
Is this by design?
I never saw the point of allowing assign to Self,...

-Flávio

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] exception handling in constructor

2013-03-01 Thread Xiangrong Fang
Hi there,

If my class constructor looks like this:

constructor TMyClass.Create(fn: string);
begin
  sl := TStringList.Create;
  try
fs := TFileStream.Create(fn, fmOpenRead);
  except
self.Destroy;
  end;
end;

I create the objec like:  MyInstance :=
TMyClass.Create('AnNonExistentFile');  An exception occured, I can ensure
that:

   1. there is no memory leak.
   2. the MyInstance variable is assigned *nil*?

Thanks
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling in constructor

2013-03-01 Thread Flávio Etrusco
On Fri, Mar 1, 2013 at 11:49 PM, Xiangrong Fang xrf...@gmail.com wrote:
 Hi there,

 If my class constructor looks like this:

 constructor TMyClass.Create(fn: string);
 begin
   sl := TStringList.Create;
   try
 fs := TFileStream.Create(fn, fmOpenRead);
   except
 self.Destroy;
   end;
 end;

 I create the objec like:  MyInstance :=
 TMyClass.Create('AnNonExistentFile');  An exception occured, I can ensure
 that:

 1. there is no memory leak.

I assume FPC behaves like Delphi, so there's no leak.
Actually, you don't even need to explicitly call Destroy; when an
exception occurs in a constructor the destructor is called
automatically.

 2. the MyInstance variable is assigned nil?

No, it's not initialized.

 Thanks

Regards,
Flávio

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-13 Thread Hans-Peter Diettrich

Bernd schrieb:

2011/3/9 Hans-Peter Diettrich drdiettri...@aol.com:


An exception down in some calculation doesn't give you any clue of what
exactly went wrong, only that *something* went wrong.


It can often be useful and remove a lot of if/else for cleanly exiting
a bunch of nested loops and functions (and also save clock cycles and
make the code much more compact and clearer) if you let it
*automatically* unwind the the call stack (instead of writing code for
this) whenever the exception occurs (of course only if you really know
why your exceptions would occur).


IMO exception handling (SEH) serves two strictly different purposes:
try-finally allows to protect resources and clean up, while
try-except allows to modify the control flow.

My comment was about proceeding after an exception occured, i.e. where 
to place the try-except block, and what to do within that exception 
handler. When a whole operation should be aborted on an invalid 
argument, raising an exception will be fine, and catching it in some 
higher level in the call stack (or in the default application handler). 
Otherwise, when the error can be detected and/or handled in the same 
place, throwing an exception can be evitable overhead.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-13 Thread Marco van de Voort
On Sat, Mar 12, 2011 at 10:53:45PM +0100, Bernd wrote:
 2011/3/9 Hans-Peter Diettrich drdiettri...@aol.com:
 
  An exception down in some calculation doesn't give you any clue of what
  exactly went wrong, only that *something* went wrong.
 
 It can often be useful and remove a lot of if/else for cleanly exiting
 a bunch of nested loops and functions (and also save clock cycles and
 make the code much more compact and clearer) if you let it
 *automatically* unwind the the call stack (instead of writing code for
 this) whenever the exception occurs (of course only if you really know
 why your exceptions would occur).

That's usually when exceptions are raised explicitely. Either by you or by
some deeper library part. Not during calculation. 

 Many people recommend not using exceptions as control structures but
 IMHO exceptions *are* control structures and can (and should) be used
 as such (if appropriate).

A big if... And it depends on the application. Specially applications that
have abortable transactions (web and db) this is useful, since one exception
and a few try finallys can safely abort the current transaction, and return
to a known good state. (waiting for next request)

In many other applications, the program is essentially in an undefined
state, and continuing is risky or useless.

 In some other languages (Python for example)
 this is even considered good programming style and recommended because
 it can make certain code much cleaner and easier to understand.

Python also considers block-by-ident good practice :-)

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-12 Thread Bernd
2011/3/9 Hans-Peter Diettrich drdiettri...@aol.com:

 An exception down in some calculation doesn't give you any clue of what
 exactly went wrong, only that *something* went wrong.

It can often be useful and remove a lot of if/else for cleanly exiting
a bunch of nested loops and functions (and also save clock cycles and
make the code much more compact and clearer) if you let it
*automatically* unwind the the call stack (instead of writing code for
this) whenever the exception occurs (of course only if you really know
why your exceptions would occur).

Many people recommend not using exceptions as control structures but
IMHO exceptions *are* control structures and can (and should) be used
as such (if appropriate). In some other languages (Python for example)
this is even considered good programming style and recommended because
it can make certain code much cleaner and easier to understand.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] exception handling

2011-03-09 Thread Andrea Mauri

Dear all,
I developed an application that perform some calculations.
This application has a gui version and a console version, it runs on 
windows and linux.
Both apps use the same units for calculation, only the interface units 
are different.

I have some problems in the exception handling.
Some calculations include ln operations.
The calculations are under try except.

Sometimes happens that the argument (a) of b:= ln(a) is negative.
The gui app handles this operation giving as result b = NaN or Inf and 
it does not raise any exception while the concole app raise an 
exception: External SIGFPE.


How can I obtain the same behaviour on my app both on GUI and console? 
Which options I have to check?


Regards,
Andrea


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-09 Thread Hans-Peter Diettrich

Andrea Mauri schrieb:


The calculations are under try except.


For what reason?

An exception down in some calculation doesn't give you any clue of what 
exactly went wrong, only that *something* went wrong.



Sometimes happens that the argument (a) of b:= ln(a) is negative.


I'd check this just before the operation, then you won't get an 
exception at all. You can wrap that in a MyLn function, if you need ln() 
more often.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-09 Thread Andrea Mauri

Il 09/03/2011 12:49, Hans-Peter Diettrich ha scritto:

I'd check this just before the operation, then you won't get an
exception at all. You can wrap that in a MyLn function, if you need ln()
more often.

ok. I know. but my question is more general and it is:

The gui app handles this operation giving as result b = NaN or Inf and 
it does not raise any exception while the concole app raise an 
exception: External SIGFPE.


How can I obtain the same behaviour on my app both on GUI and console? 
Which options I have to check?


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-09 Thread Mattias Gaertner
On Wed, 09 Mar 2011 14:17:19 +0100
Andrea Mauri andrea.mauri...@gmail.com wrote:

 Il 09/03/2011 12:49, Hans-Peter Diettrich ha scritto:
  I'd check this just before the operation, then you won't get an
  exception at all. You can wrap that in a MyLn function, if you need ln()
  more often.
 ok. I know. but my question is more general and it is:
 
 The gui app handles this operation giving as result b = NaN or Inf and 
 it does not raise any exception while the concole app raise an 
 exception: External SIGFPE.
 
 How can I obtain the same behaviour on my app both on GUI and console? 
 Which options I have to check?

Some LCL widgetsets use this:

  {$if defined(cpui386) or defined(cpux86_64)}
{$IFDEF windows}
  Set8087CW($133F);
{$ELSE}
  SetExceptionMask(GetExceptionMask + [exZeroDivide,exInvalidOp]);
{$ENDIF}
  {$ifend}


Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] exception handling

2011-03-09 Thread Andrea Mauri

Il 09/03/2011 17:29, Mattias Gaertner ha scritto:

Some LCL widgetsets use this:

   {$if defined(cpui386) or defined(cpux86_64)}
 {$IFDEF windows}
   Set8087CW($133F);
 {$ELSE}
   SetExceptionMask(GetExceptionMask + [exZeroDivide,exInvalidOp]);
 {$ENDIF}
   {$ifend}


thanks!

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] Exception handling in LCLMessageGlue

2010-08-18 Thread Torsten Bonde Christiansen

 Hi Lazarus.

Please forgive my ignorance if I'm asking a stupid question.

In the DeliverMessage function in LCLMessageGlue the 
Application.HandleException is called with __nil__ as argument. Why is 
the actual target used here? It is already available at this point, and 
the callback function added with AddOnExceptionHandler supports passing 
the target as parameter.


I'm not an expert on exception handling and the inner working on the 
LCL, but from what my research have shown I think it should be possible.


Kind regards,
Torsten Bonde Christiansen.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus