This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: global {con,de}structors, atexit & friends
- To: egcs at cygnus dot com
- Subject: Re: global {con,de}structors, atexit & friends
- From: Oleg Zabluda <zabluda at math dot psu dot edu>
- Date: Sun, 26 Jul 1998 13:15:51 -0400 (EDT)
- Newsgroups: oleg.egcs
- Organization: Penn State University, Center for Academic Computing
- Reply-To: zabluda at math dot psu dot edu (Oleg Zabluda)
In article <r23ebpgbs3.fsf@happy.cygnus.com> you wrote:
: Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de> writes:
: > - The __DYNAMIC_DTOR_LIST__, is it per shared object, or global (per
: > process). If per shared object (i.e. one for each shared library),
: > how do you handle the interleaving of destructors across shared
: > objects? I.e.
: >
: > void f(){ //a.so
: > static A x;
: > }
: >
: > void g(){ //b.so
: > static B x;
: > f();
: > static B y;
: > }
: >
: > This could be solved by making the DTOR_LIST a list and not an
: > array. Of course, inserting an element in the front of the chain
: > is more expensive in a MT environment.
: I don't think that giving any guarantee that the constructors in
: different objects (main program, shared objects) are run in any
: specific order. I consider these objects as individual programs which
: "accidently" share the same address space.
The C++ Standard does not gurantee the order of construction of global
objects with static storage duration, defined in different translation
units. However, it guarantees that their destructors are run in the
reverse order of completion of their constructors. The Standard is more
explicit for the case of local static objects (the one in question
here). It says that local statics are initialized only once when the
execution flow first passes over their definition. It also gurantees
the order of destruction, just like for global statics.
Unfortunately, the correct compiler behaviour for local statics is
extremely important, and all bugs in this area are very far from being
"obscure", so that nobody cares about them. Local statics are used in
95% of implementations of the Singleton Pattern, which, I think, atpresent
is used as often as all other patterns combined.
The reason local statics are used for the Singleton implementation
in the first place, is to automate (dump it on the compiler) all
the manual work related with ensuring that the construction
happens exactly once. It would be an enourmous help if the
compiler would indeed do it right.
The Statndard says nothing about multithreading, so it's
arguable whether ensuring initialization once and only once
in the presence of multithreading is required. Some say that
the ISO C++ alone does not require that, but the combination
of ``ISO C++'' + "Pthreads" strogly implies that. It seems
to me from my exprementations that egcs does it right
in the presence of multiple threads, which is great.
There is one serious, albeit well-known, real bug in the
current egcs. That is, if the constructor of local static
throws an exception, egcs still thinks that it was constructed,
and does not try again next time.
Here is a test case:
#include <iostream.h>
struct A { A() { cerr << "A()\n"; throw 0; } };
int main() { for(;;) try { static A a; } catch(int) {} }
This is supposed to loop forever and keep printing ``A()''. Currently
it prints it only once.
Oleg.