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

2009-07-02 Thread Martin Friebe

Inoussa OUEDRAOGO wrote:

2009/6/29 Tom Verhoeff :
  

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
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


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

2009-07-02 Thread Michael Van Canneyt



On Thu, 2 Jul 2009, Martin Friebe wrote:


Inoussa OUEDRAOGO wrote:

2009/6/29 Tom Verhoeff :


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?


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.

Construction is handled very specially by the compiler. 
The special exception frame is in the constructor helper code. 
Your own routine does not get an extra exception frame.


For instance:

procedure DOCreate;

begin
 TMyObject.Create;
end;

Results in the following (64-bit) assembler:

.globl  P$TESTCF_DOCREATE
.type   P$TESTCF_DOCREATE,@function
P$TESTCF_DOCREATE:
pushq   %rbp
movq%rsp,%rbp
movq$VMT_P$TESTCF_TMYOBJECT,%rsi
movq$0,%rdi
callP$TESTCF_TMYOBJECT_$__CREATE$$TMYOBJECT
leave
ret

As you can see, there is no extra exception frame.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


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

2009-07-02 Thread Martin Friebe

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



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)?



Thanks for the explanation so far
Martin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


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

2009-07-02 Thread Michael Van Canneyt



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


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


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

2009-07-02 Thread Jonas Maebe


On 02 Jul 2009, at 16:58, Martin Friebe wrote:

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)?


http://www.freepascal.org/docs-html/prog/progsu32.html

It also applies to the exception frames in constructors.

Note that while that page says it is set to OFF by default, it's  
obviously set to ON by default. That error has already been corrected  
in the svn version of the documentation.



Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


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

2009-07-02 Thread Martin Friebe

Jonas Maebe wrote:

On 02 Jul 2009, at 16:58, Martin Friebe wrote:
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)?


http://www.freepascal.org/docs-html/prog/progsu32.html

It also applies to the exception frames in constructors.


thanks a lot
Martin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal