Topic: static object construction/destruction order


Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/06/22
Raw View
In article <31C87E03.41C6@vnet.ibm.com> James Keesey
<keesey@vnet.ibm.com> writes:

|> Greg Silverman wrote:
|> >
|> > The ARM says that static objects in a translation unit are constructed
|> > in the order their definitions appear in the file and that destructors
|>                                                ^^^^
|> > are called in reverse order. I did the following experiment on Solaris
|> > 2.5 using Sun's version 4.1 compiler:
|> >
|> [snip...]
|> >
|> > Thus, in a global sense, the objects were not destructed in reverse of
|>              ^^^^^^
|> > the order in which they were constructed. Is this correct C++?
|> >

|> Static object construction/destruction order is only defined within
|> each file/translation unit.  In your example, the destructors were
|> called in reverse order in each file so the behavior is correct.

Construction order was (and still is) only defined within a translation
unit.  The order of destruction, as describe in the ARM, was (and still
is) the opposite of the order of construction.  The only ambiguity was
whether the destructors for local static objects were included in this
ordering.  (To be precise, the order of destruction is undefined
*because* the order of construction is undefined.  The relationship
between the two *IS* defined.)

|> There have been many "discussions" ;) about what way is "the right way"
|> but this is the way that the standard (and I believe the ARM) states.

The standard (at least the last version I have access to) has clarified
the remaining point: local static objects are included in the ordering.

|> [soapbox on]
|> I still believe that the overhead can't be so great as to preclude
|> requiring the compilers to remember the order of all static object
|> construction and destruct them in the reverse order.
|> [soapbox off]

I believe that this is what is required.  My interpretation of the ARM
was that this was what was required there.  Most implementers, however,
seemed to disagree with me.  (At least, I've yet to come across an
implementation which maintaint the LIFO ordering across both local and
non-local statics.)  I suspect the main reason most implementers
maintained this point of view is the fact that it is generally possible
to maintain the correct ordering amonst non-local statics without
runtime registration.  Adding local statics imposes the runtime
registration in all cases, since the order of construction can depend
on runtime program flow, and may vary from one run to the next.
--
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: vonbrand@inf.utfsm.cl (Horst von Brand)
Date: 1996/06/25
Raw View
In article <31C0B99D.639C@smtp.svl.trw.com>,
Greg Silverman  <greg_silverman@smtp.svl.trw.com> wrote:
>The ARM says that static objects in a translation unit are constructed
>in the order their definitions appear in the file and that destructors
>are called in reverse order. I did the following experiment on Solaris
>2.5 using Sun's version 4.1 compiler:
>[...]
>[Construction order: 0, 1 in x1.cc; 2, 3 in x2.cc; ...]
>[Destruction order:  1, 0 in x1.cc; 3, 2 in x2.cc; ...]
>Thus, in a global sense, the objects were not destructed in reverse of the
>order in which they were constructed. Is this correct C++?

Yes. As you quote above, the ARM talks about the order of
construction/destruction _in a translation unit_, not among translation
units. It would even be valid to construct:

0 in x1.cc, 2 in x2.cc, 1 in x1.cc, 3 in x2.cc, ...

as long as 0 is constructed before 1, 2 is constructed before 3, ...  and
to destruct similarly.  The matter is discussed by B. Stroustrup in his
"C++ Programming Language", 2ed and/or "Design and Evolution of C++".  He
gives a solution for the (rare) case where you need to order stuff by
creating a static object of a class with a static counter member in each
translation unit.  As a static member, it is guaranteed to start off at 0,
and in the constructor you test for that and increment, in the destructor
you decrement and test for 0.  Something along the lines:

class serializer {
static int count ;
public:
serializer()  {if(count++ == 0) do_initialize_the_world();};
~serializer() {if(--count == 0) do_destruct_the_world();};
}



--
Dr. Horst H. von Brand                          vonbrand@inf.utfsm.cl
Departamento de Informatica                     Fono: +56 32 626364 x 431
Universidad Tecnica Federico Santa Maria        Fax:  +56 32 625217
Casilla 110-V, Valparaiso, Chile


[ 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: Greg Silverman <greg_silverman@smtp.svl.trw.com>
Date: 1996/06/19
Raw View
The ARM says that static objects in a translation unit are constructed
in the order their definitions appear in the file and that destructors
are called in reverse order. I did the following experiment on Solaris
2.5 using Sun's version 4.1 compiler:

 //file x1.cc
 ...
 extern int count;

class test {
   public:
     test()
          { _m = count++; cout << "Constructing object" << _m << " in file "
<< __FILE__ << "\n";}
     ~test()
           { cout << "Destructing  object " << _m << " in file " << __FILE__
<< "\n";}
   private:
     int _m;
 };

static test t1;
static test t2;

<eof>

I had files x2.cc, x3.cc, and x4.cc which are unaltered copies of x1.cc. I had
a file m.cc that looked as follows

//m.cc

int count;
int main()
{
}

I built the program x as follows :

CC -o x x1.cc x2.cc x3.cc x4.cc m.cc

where m.cc contains nothing more than main. I got following output

Constructing object 0 in file x1.cc

Constructing object 1 in file x1.cc

Constructing object 2 in file x2.cc

Constructing object 3 in file x3.cc
.
.
.
Constructing object 7 in file x4.cc

Destructing object 1 in file x1.cc

Destructing object 0 in file x1.cc

Destructing object 3 in file x2.cc

Destructing object 2 in file x2.cc

Destructing object 5 in file x3.cc

Destructing object 4 in file x3.cc

Destructing object 7 in file x4.cc

Destructing object 6 in file x4.cc


Naming the objects in the order the were constructed, the object were
constructed in the following order :


object 0, object 1, object 2, ..., object 7.

Listing the objects in the order the were destructed, we have:

object 1, object 0, object 3, object 2, object 5, object 4, object 7, object 6


Thus, in a global sense, the objects were not destructed in reverse of the
order in which they were constructed. Is this correct C++?


Greg Silverman
TRW/SIG
Sunnyvale, Ca
---
[ 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: James Keesey <keesey@vnet.ibm.com>
Date: 1996/06/20
Raw View
Greg Silverman wrote:
>
> The ARM says that static objects in a translation unit are constructed
> in the order their definitions appear in the file and that destructors
                                               ^^^^
> are called in reverse order. I did the following experiment on Solaris
> 2.5 using Sun's version 4.1 compiler:
>
[snip...]
>
> Thus, in a global sense, the objects were not destructed in reverse of the
             ^^^^^^
> order in which they were constructed. Is this correct C++?
>

Static object construction/destruction order is only defined within
each file/translation unit.  In your example, the destructors were
called in reverse order in each file so the behavior is correct.

There have been many "discussions" ;) about what way is "the right way" but
this is the way that the standard (and I believe the ARM) states.

[soapbox on]
I still believe that the overhead can't be so great as to preclude requiring
the compilers to remember the order of all static object construction and
destruct them in the reverse order.
[soapbox off]

--

James Keesey                              Internet: keesey@vnet.ibm.com
IBM Santa Teresa Labs                         VNET: KEESEY at STLPS
DB2 Multimedia Extenders
---
[ 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                             ]