Re: [Lazarus] exception handling in constructor
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
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
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
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
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
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
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
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/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
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
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
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
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
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
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