From: jamshid@ut-emx.uucp (Jamshid Afshar)
Newsgroups: comp.lang.c++
Subject: Order of static object construction/destruction (was "Re: Overlays")
Summary: first constructed must be last destroyed
Date: 7 Apr 92 00:59:27 GMT
Reply-To: jamshid@emx.utexas.edu
Organization: The University of Texas at Austin; Austin, Texas

In article <1992Apr01.182529.19525@demon.co.uk> N Locke - Trumphurst Ltd <nikki@cix.compulink.co.uk> writes:
>The only problem then is that the ARM does not say in which order static
>constructors from different files are called. Worse, those nice
>Borland people have chosen to call the destructors IN THE SAME ORDER
>as the constructors, which is pretty stupid IMHO.

It's also just plain wrong ITANSO (In The ARM's Not So Humble Opinion
:-).  While the order of the construction of non-local[1] static[2]
objects across files is undefined, ARM 3.4 is very clear in requiring
an implementation to
	a) within a file, construct static objects in the order in
	   which they are defined[3]
	b) destroy all these static objects in the reverse order in
	   which they were constructed, even across files

So whatever order your compiler chooses to construct your program's
static objects, it must destroy them all in the reverse order.

Back in November 1991 I sent the appended bug report to
bugs@borland.com (there is no Borland tech. support address -- this
just for reporting reproducable bugs).  I guess they didn't have time
to get the fix into BC++ 3.0 which was released in December.

[1] Local (to a function) objects are only constructed (and therefore
    destroyed) if the function is called.  It is constructed the first
    time the function is called and destroyed either immediately
    before or as part of the atexit() functions.  (ARM 6.7)
[2] The term `static' here means storage class: "allocated once at
    a fixed address", not necessarily scope (as in local to a file
    or class), so this applies to static data members, global variables,
    and file scope static variables.  (ARM 7.1.1)
[3] This doesn't mean an implementation must construct all a file's
    static objects at once -- it could do the first one in each file,
    then the second and third in each, or postpone construction until
    the first use of a function or object defined in the file.

Jamshid Afshar
jamshid@emx.utexas.edu

/*
Filenames: FOO.H, ONE.CPP, TWO.CPP
Compile: bcc one.cpp two.cpp  (BC++ 2.0 [and 3.0])
Submitted by: Jamshid Afshar (jamshid@emx.utexas.edu) 512-471-1702
Discoverd by: Nikki Locke - Trumphurst Ltd <nikki@cix.compulink.co.uk>
Problem:
   Destruction of static objects should be done in reverse order
   of initialization, even across modules.  For example, if module
   ONE's objects are constructed first, module TWO's objects should
   be destroyed first.   I believe the ARM 3.4 p21  requires this,
   but even if it doesn't, it's much more reasonable behavior than
   what BC++ currently does: ONE's objects are constructed first
   and destroyed first.
Workaround:
   Put all static objects in one .cpp file since Borland does handle
   destruction order correctly within a file.
*/

/////////////// begin FOO.H ////////////
#ifndef FOO_H
#define FOO_H

#include <stdio.h>

class Foo {
private:
   const char* _module;
public:
   Foo(const char* module) : _module(module) {
      printf("Constructing %s's Foo.\n", _module);
      }
   ~Foo() {
      printf("Destroying %s's Foo.\n", _module);
      }
};

#endif // FOO_H
/////////////// end FOO.H ////////////

/////////////// begin ONE.CPP ////////////
#include "foo.h"

Foo one(__FILE__);

main() { return 0; }
/////////////// end ONE.CPP ////////////

/////////////// begin TWO.CPP ////////////
#include "foo.h"

Foo two(__FILE__);
/////////////// end TWO.CPP ////////////