implicit exception frames? [Re: [fpc-pascal] If an Assert fails in constructor, then destructor called (?)]

Martin Friebe fpc at mfriebe.de
Thu Jul 2 16:03:23 CEST 2009


Inoussa OUEDRAOGO wrote:
> 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.
>   
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?

Anyway, as I said it's not necessarily bad behaviour. but given that 
exception handling may add to runtime cost, is there a way to switch 
this off?
Like
 {$AutoDestroty off}
 try
   foo := TFoo.create;
 except
   if foo <> nil then foo.free;
 end;



Martin



More information about the fpc-pascal mailing list