[fpc-pascal] If an Assert fails in constructor, then destructor called (?)
Inoussa OUEDRAOGO
inoussa12 at gmail.com
Tue Jun 30 20:58:47 CEST 2009
2009/6/29 Tom Verhoeff <T.Verhoeff at tue.nl>:
> While tracing a nasty bug (?), I discovered the hard way that when
> an Assert is done in a constructor, and it fails, then the destructor
> (Destroy) is automatically called.
Indeed, when an exception is raised in the constructor, be it an
"assert" exception or not, the destructor is called to allow the
developer to clean up the "in-construction" instance's members he has
already initialized.
> However, because the constructor failed, the object did not satisfy the
> class invariants.
>
> So, the destructor needs to be pessimistic about the state.
> Mine was not.
It has to, see below.
> Since the Assert in the constructor is there to protect against
> parameter values that do not statisfy the constructor's precondition,
> there are no additional dynamic veriables and objects created, and
> hence they need not be destroyed.
> How can the destructor know that it is called in such a state?
At object creation, the instance's memory is "zeroed" so that integers
are zero, pointers are nil, boolean are false, strings are empty
strings, dynamic arrays are nil(zero length) ...
So in your case if "FList" is not nil, you filled it.
> Below is a simple example to illustrate the problem.
> My destructor assumed that the class invariants hold,
The destructor has not to. It must prepare to handle both cases (
invariants hold and not ).
> of the class methods to aid in tearing down the object. Except
> that the object does not exist if the destructor gets called because
> of the failed Assert in the constructor.
Wrong. The object _does exists_ : its memory has been allocated and
zeroed. With regard to the compiler/RTL, at the constructor entry
point, the instance is valid. Please remember that the compiler is not
aware of _your_ class invariants.
Other important point : Object Pascal instance construction is not
done the same way as in C++ where the object is completely constructed
at the end of the constructor. In Object Pascal it is even valid to
call virtual methods in the constructor, that is possible because at
the constructor entry point the instance actual type is definitely
fixed.
This blog* by Herb Sutter explains the C++/C#/Java object construction
mecanism. Make a special attention to the first** comment by Barry
Kelly*** where he explains the Delphi way and its difference with
regard to C++/C#/Java.
foot note :
* http://herbsutter.wordpress.com/2008/07/25/constructor-exceptions-in-c-c-and-java/
** http://herbsutter.wordpress.com/2008/07/25/constructor-exceptions-in-c-c-and-java/#comment-716
*** Delphi compiler engineer http://barrkel.blogspot.com/
--
Inoussa O.
More information about the fpc-pascal
mailing list