[comp.lang.c++] conditional scope and destructors

pmoore@hemel.bull.co.uk (Paul Moore) (11/09/90)

This is a problems I had writing dos code with zortech 2.1 but it is a general
problem with c++ - something is not tightly defined.

Problem:- if an object is only created conditionally in a function should
its destructor be called at function exit?

Example:-

func(..)
.....
	if (foo==bar)
		return(z);
.....
	object obj1;
....
}
If foo does equal bar then obj is not created - should its destructor be
called when the return is done? Zortech 2.1 does call it. 
It seems to me this is a bug , but Strousop doesnt really discuss this point
as far as I can see. What do other compilers do?
(The above example is trivial - the declaration of obj could be placed at
the start of func. This is not the case where the constructor takes
arguments that must be calculated before the declaration).

The actual problem I had was that the filebuf destructor blew up when I
had a conditional declaration of filebuf that wasnt invoked.

steve@taumet.com (Stephen Clamage) (11/11/90)

pmoore@hemel.bull.co.uk (Paul Moore) writes:

|Problem:- if an object is only created conditionally in a function should
|its destructor be called at function exit?

No.

|func(..)
|.....
|	if (foo==bar)
|		return(z);
|.....
|	object obj1;
|....
|}
|If foo does equal bar then obj is not created - should its destructor be
|called when the return is done? Zortech 2.1 does call it. 
|It seems to me this is a bug.

It is a bug.  A destructor must not be called for an object which has not
been constructed.  It is up to the compiler to call exactly the right
destructors.  This is well-defined in the language.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

Bruce.Hoult@actrix.co.nz (Bruce Hoult) (11/11/90)

>If foo does equal bar then obj is not created - should its destructor
>be called when the return is done? Zortech 2.1 does call it.
 
It is probably bad form to put a return statement other than at the end
of the function -- especially for maintenance reasons. You could put
the rest of the function body in an "else" clause, or even just in {}
to create a new scope.
 
Because the object was declared in the function scope (rather than in
some enclosed scope within the function) it actually exists for the
entire execution of the function.  The error is not the compiler
calling the destructor, but your failure to ensure that it is correctly
constructed in all possible execution paths.

jimad@microsoft.UUCP (Jim ADCOCK) (11/13/90)

In article <1990Nov9.151803.11426@hemel.bull.co.uk> pmoore@hemel.bull.co.uk (Paul Moore) writes:
>This is a problems I had writing dos code with zortech 2.1 but it is a general
>problem with c++ - something is not tightly defined.
>
>Problem:- if an object is only created conditionally in a function should
>its destructor be called at function exit?
>
>Example:-
>
>func(..)
>.....
>	if (foo==bar)
>		return(z);
>.....
>	object obj1;
>....
>}
>If foo does equal bar then obj is not created - should its destructor be
>called when the return is done? Zortech 2.1 does call it. 

Issues of construction and destruction in the presence of conditional
statements has been a confusing issue in the past -- especially since
most compilers seem to have some problems in these areas.

Section 6 seems to clarify what is expected considerably:

A declaration is a statement that is expected to be executed everytime
it is hit.  For every time an object is constructed, it is expected
to be destructed.  A jump forward over an initializer statement is
illegal unless that initializer statement is in an inner block wholey
skipped over.  A jump backwards over an initializer statement is legal
and causes the destructor to be invoked before the object is initialized again.
An object's destructor is not invoked unless that object has been 
constructed, and exiting a scope destroys objects constructed therein.

Translated into pidgin C, the results of your example should be as if:

func(..)
{
    .....
    if (foo==bar)
    {
        return(z);
    }
    else
    {
        .....
        struct object obj1;
        construct_object(&obj1);
        ....
        destruct_object(&obj1);
    }
}