Topic: what happens at exit?


Author: bermudj@westminster.ac.uk (Tony Bermudez)
Date: 1996/06/04
Raw View
before anything else, thanks for any replies.

given

#include <iostream.h>
#include <stdlib.h>

class X
{
public:
 X() { cerr << "creating x\n"; exit(0); }
};

class Y
{
public:
 Y() { cerr << "never executed\n"; }
 ~Y() { cerr << "destroying y\n"; }
};

X x;
Y y;

int main()
{
 return 0;
}

some compilers (g++) when they hit the exit, they just termninate, whereas
others (borland c++ ) start executing the destructors before terminating. The
latter means that a destructor may be invoked for an object, although
its constructor has not. The former means one can not rely on a
destructor to save a file or perform a similar task.

could someone shed some light on what should happen? thank you.

tony
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/06/04
Raw View
In article <4ov0ch$ktl@badger.wmin.ac.uk> bermudj@westminster.ac.uk
(Tony Bermudez) writes:

|> before anything else, thanks for any replies.

|> given

|> #include <iostream.h>
|> #include <stdlib.h>

|> class X
|> {
|> public:
|>  X() { cerr << "creating x\n"; exit(0); }
|> };

|> class Y
|> {
|> public:
|>  Y() { cerr << "never executed\n"; }
|>  ~Y() { cerr << "destroying y\n"; }
|> };

|> X x;
|> Y y;

|> int main()
|> {
|>  return 0;
|> }

|> some compilers (g++) when they hit the exit, they just termninate, whereas
|> others (borland c++ ) start executing the destructors before terminating.
|> The latter means that a destructor may be invoked for an object, although
|> its constructor has not. The former means one can not rely on a
|> destructor to save a file or perform a similar task.

|> could someone shed some light on what should happen? thank you.

Neither behavior is correct, and I don't believe that you accurately
describe what g++ does either.  (I am fairly sure that it calls the
destructor for all initialized statics.)

The latest DWP says that "Destructors for initialized objects of static
storage duration are called when returning from main and when calling
exit."  This seems both clear and reasonable to me, at least with
regards to complete objects.  In your example, the operative word is
"initialized"; when "exit" is called in X::X(), there are no initialized
static objects, so no destructors should be called.

I'm less sure about what happens with partial objects.  Suppose I declare:

    struct Z { Y y ; X x } ;        //  X and Y as above.

    Z z ;

    int main() {}

I think that the destructor for the Y part of z should be called when
the constructor for the X part calls exit.  It would be nice if the
standard were very explicit about this, though.


--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
                -- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Duncan Booth <duncan@rcp.co.uk>
Date: 1996/06/04
Raw View
In article <4ov0ch$ktl@badger.wmin.ac.uk> on  bermudj@westminster.ac.uk
(Tony Bermudez) wrote:>
> before anything else, thanks for any replies.
>
> given
>
> #include <iostream.h>
> #include <stdlib.h>
>
> class X
> {
> public:
>  X() { cerr << "creating x\n"; exit(0); }
> };
>
> class Y
> {
> public:
>  Y() { cerr << "never executed\n"; }
>  ~Y() { cerr << "destroying y\n"; }
> };
>
> X x;
> Y y;
>
> int main()
> {
>  return 0;
> }
>
> some compilers (g++) when they hit the exit, they just termninate,
whereas
> others (borland c++ ) start executing the destructors before
terminating. The
> latter means that a destructor may be invoked for an object, although
> its constructor has not. The former means one can not rely on a
> destructor to save a file or perform a similar task.
>
> could someone shed some light on what should happen? thank you.
>

In your example g++ is correct and borland is wrong. When exit is
called, the destructors of all constructed objects must be destroyed in
the reverse of the order in which they are created. Your example, when
exit is called has no objects to destroy. Y was never constructed, and
the constructor for X has not completed.

If you add a destructor for X you will see that that is not called
either as X has not been completely constructed at the point when the
program exits. If you construct another object (W?) before X then you
should see that the destructor for W is called on exit.

This means that you can rely on a destructor to save a file or similar,
but only if the object that is destroyed has been fully constructed. It
is still a dangerous trick though, because when static objects are being
destroyed you cannot be sure exactly which other objects (defined in
other files) still exist.

The compiler I use produces initialisation code that calls the
constructor for a static object, then immediately after the constructor
returns calls atexit with the destructor as a parameter. This ensures
that the correct behaviour is always followed exactly even in respect of
user calls to atexit made from within static object constructors which
are then interleaved with the destructors.

If you want to be sure that your files are tidied up, try calling atexit
yourself at appropriate points in the initialisation.

Duncan Booth
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]