implicit exception frames? [Re: [fpc-pascal] If an Assert fails in constructor, then destructor called (?)]
Michael Van Canneyt
michael at freepascal.org
Thu Jul 2 17:09:24 CEST 2009
On Thu, 2 Jul 2009, Martin Friebe wrote:
> Michael Van Canneyt wrote:
>> On Thu, 2 Jul 2009, Martin Friebe wrote:
>>> Inoussa OUEDRAOGO wrote:
>>>> 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.
>>>>
>>> I just cam across this thread. While I am not opposing the behaviour as
>>> it's stand (it could be useful anyway), it raises another question.
>>>
>>> Does that mean that an implicit exception-frame (or whatever this is
>>> called) is inserted *each* time you create/instantiate an object?
>>>
>>> Now I understand, object instantiation comes at a cost anyway (memory
>>> allocation), this does add to the cost of instantiation. And the only
>>> error/exception, which really *all* classes can encounter in a
>>> constructor, is out of memory for the object itself => In which case
>>> create is never called (because NewInstance fails), and Destroy should not
>>> be called (as there is no instance that could be passed to destroy).
>>> So There could be calls to create where a developer does not want (and not
>>> need) any exception stack frame.
>>>
>>> I also wonder why this special kind of "garbage collector"? Pascal has
>>> automatic behaviour to handle/free resources for:
>>> - strings
>>> - open array
>>> - apparently classes/objects, but only inside the constructor ?
>>>
>>> The last one does of course not apply to objects hold by the failed
>>> object, but I assume that, if Destroy is called, the instance is also
>>> freed?
>>> So why are objects handled special in the constructor? If they raise an
>>> exception anywhere else in there live, then you need to care yourself
>>> about catching it, and freeing them?
>>
>> Because you cannot handle it yourself. Assume the following statement:
>>
>> MyClass:=TSomeClass.Create;
>>
>> if an exception happens inside the constructor, then no instance pointer is
>> assigned to MyClass, since execution after the exception is raised is
>> continued at the next except/finally block.
>> That means you cannot handle destruction in the except block (assuming you
>> wrote one) since you have no pointer to work with.
>>
>> Therefor the constructor code must call the destructor in case of an error.
> Yes, of course, you are right. It is impossible to handle it in the calling
> code. As the order is:
> - instantiation (NewInstance)
> - Create
> - exception
> - assignment to local var => never executed
>
> But you can handle it yourself inside the constructor.
> No one stops the developper from wrtiting
>
> Constructor TFoo.Create;
> begin
> try
> ...
> except
> self.Destroy; // Or Free ?
> end;
> end;
>
>
> - If an error/exception (out of mem) happens in NewInstance, neither Create
> nor Destroy are called (and neither can they be called, because they need an
> (empty) instance and there is none)
> - If an error in Create happens, self is assigned (inside Create). So it can
> be acted on.
> Even if, in the above example, this Create was called by a child-class via
> inherited Create. There is no worry (not even if self.Free is used), that the
> inherited constructor will find an invalid pointer in self (because/if it has
> been freed). The code above, never returns to the inherited constructor,
> unless this inherited constructor itself catches the exception too (in which
> case it must check ; It would need to be flagged on the exception object)
>
> Anyway, while possible, it would be far to complicated. So I agree, the
> automated handling, ensuring the instance is Destroyed and freed once only,
> is probably the best
Yes, because there is no way to know what happens in the
constructor/destuctor in a descendent/parent class...
>
>
> Leaves question 2: Is there a way to switch it off, to avoid the cost of
> creating an exception frame? (if you are either sure your constructor does
> not throw an exception, or for some reason do not care)?
Not that I am aware of. But someone familiar with the compiler internals
should confirm this.
Michael.
Michael.
>
>
> Thanks for the explanation so far
> Martin
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
More information about the fpc-pascal
mailing list