Topic: Order of static deinitialization


Author: comeau@panix.com (Greg Comeau)
Date: 2000/10/11
Raw View
In article <39E49B3B.8EEC011B@sensor.com>, Ron Natalie  <ron@sensor.com> wrote:
>Edward Diener wrote:
>It doesn't say anything at all about statics defined at class scope.
>
>class A {
>static C a_c;
>};
>class B {
>static C b_c;
>};
>
>A a;
>B b;
>
>doesn't make any particular guarantees about the destruction order
>of a_c and b_c; since they are at class scope.

But when they are defined the will appear in namespace scope.

- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Yaroslav Mironov" <tada@mail.wplus.net>
Date: 2000/10/11
Raw View
Edward Diener wrote:
>Yaroslav Mironov wrote:

[skip]

>> >> To my great surprise some of tested compilers preferred to do the
latter.
>> >
>> >That is clearly wrong.
>> >Please tell us which compilers do that.
>>
>> Notorious Borland C++ 5.5 for Win32
>
>You stated:
>
>"To my great surprise some of tested compilers preferred to do the latter."
>
>Which other compilers beside Borland C++ 5.5 for Win32 are incorrect ?

Only this one, I found no other.


I wrote that first letter right away when I found that strange bahavior of
BC, so in fact it was the only compiler tested. Since then I've checked
several compilers, but none of them produces this error.

>The interesting thing is that if the static objects are moved outside of
the
>functions, the order of the destructors is correct in Borland C++ 5.5

I think destructors are called there in the reverse order of appearing of
static objects in the code.

Yaroslav


PS Sorry for delayed reply, I was too busy to read the newsgroup


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Edward Diener <eddielee@abraxis.com>
Date: 2000/10/11
Raw View
Yaroslav Mironov wrote:

> Edward Diener wrote:
> >Yaroslav Mironov wrote:
>
> [skip]
>
> >> >> To my great surprise some of tested compilers preferred to do the
> latter.
> >> >
> >> >That is clearly wrong.
> >> >Please tell us which compilers do that.
> >>
> >> Notorious Borland C++ 5.5 for Win32
> >
> >You stated:
> >
> >"To my great surprise some of tested compilers preferred to do the latter."
> >
> >Which other compilers beside Borland C++ 5.5 for Win32 are incorrect ?
>
> Only this one, I found no other.
>
> I wrote that first letter right away when I found that strange bahavior of
> BC, so in fact it was the only compiler tested. Since then I've checked
> several compilers, but none of them produces this error.
>
> >The interesting thing is that if the static objects are moved outside of
> the
> >functions, the order of the destructors is correct in Borland C++ 5.5
>
> I think destructors are called there in the reverse order of appearing of
> static objects in the code.

Which is correct as AFAIK. Is it possible that local static objects do not have
to be destroyed in the reverse order in which they are created ? I recall
another post by Scott Meyers in which the correct
initialization/deinitialization sequence of static objects was only guaranteed
for static objects at namespace scope, the gist being that class static objects
when defined were at namespace scope, but a static object within a function, a
local static object, does not seem to be at namespace scope.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/11
Raw View

Edward Diener wrote:
>
> Which is correct as AFAIK. Is it possible that local static objects do not have
> to be destroyed in the reverse order in which they are created ? I recall
> another post by Scott Meyers in which the correct
> initialization/deinitialization sequence of static objects was only guaranteed
> for static objects at namespace scope, the gist being that class static objects
> when defined were at namespace scope, but a static object within a function, a
> local static object, does not seem to be at namespace scope.

It says at BLOCK or NAMESPACE scope.  So statics inside functions and those outside
are destructed in the inverse order of their construction at program exit.  The original
poster showed statics at block scope, his compiler was wrong to not destroy them in
the opposite order of their initialization.  i.e.:

class C { ... };

C a;
C b;

void func1() {
   static C c;
}
void func2() {
   static C d;
}

int main() {
   func2();
   func1();
}

Should construct : a b d c
and destruct:      c d b a

It doesn't say anything at all about statics defined at class scope.

class A {
static C a_c;
};
class B {
static C b_c;
};

A a;
B b;

doesn't make any particular guarantees about the destruction order of a_c and b_c;
since they are at class scope.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Roger Orr <roger_orr@my-deja.com>
Date: 2000/10/08
Raw View
In article <STbD5.298$ZR2.114322@nnrp1.sbc.net>,
  Bill Wade <wrwade@swbell.net> wrote:

> It also gave programmers significantly bigger
> headaches.

...which can be reduced by trying to avoid code which depends on the
order of construction and destruction of statics.

I know sometimes this _can't_ be avoided - but code with such
dependencies which are unnecessary seems quite common, alas.

Roger.
--
MVP in C++ for Brainbench at http://www.brainbench.com


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Yaroslav Mironov" <tada@mail.wplus.net>
Date: 2000/10/05
Raw View
Hello,

Dennis Yelle wrote:

>Yaroslav Mironov wrote:
>>
>> Hello,
>>
>> Is it guaranteed that the order in which destructors of static objects
are
>> called is exactly the reverse order of the completion of their
constructors?
>>


[skip]

>> So, is it a must for a conforming compiler to have the output like:
>> b ctor
>> a ctor
>> a dtor
>> b dtor
>>
>> And not:
>> b ctor
>> a ctor
>> b dtor
>> a dtor
>>
>> To my great surprise some of tested compilers preferred to do the latter.
>
>That is clearly wrong.
>Please tell us which compilers do that.


Notorious Borland C++ 5.5 for Win32

The code compiled was exactly that from my previous letter, all compilator
options are by default.

The output was:
b ctor
a ctor
b dtor
a dtor

Yaroslav


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Bill Wade <wrwade@swbell.net>
Date: 2000/10/06
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote

> That is clearly wrong.
> Please tell us which compilers do that.

IIRC older (probably C-front based) compilers on some systems would destruct
all static objects (global and local) in a translation unit in bottom-to-top
order (skipping locals that were never constructed).

This probably made writing the compiler slightly easier, and may have made
the code slightly faster.  It also gave programmers significantly bigger
headaches.


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/06
Raw View

Bill Wade wrote:
s do that.
>
> IIRC older (probably C-front based) compilers on some systems would destruct
> all static objects (global and local) in a translation unit in bottom-to-top
> order (skipping locals that were never constructed).
>
> This probably made writing the compiler slightly easier, and may have made
> the code slightly faster.  It also gave programmers significantly bigger
> headaches.
>
Only very slightly.  Since it still has to remember which statics had been
initialized and which weren't, it is only a tiny bit harder to keep them in
order.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Edward Diener <eddielee@abraxis.com>
Date: 2000/10/06
Raw View
Yaroslav Mironov wrote:

> Hello,
>
> Dennis Yelle wrote:
>
> >Yaroslav Mironov wrote:
> >>
> >> Hello,
> >>
> >> Is it guaranteed that the order in which destructors of static objects
> are
> >> called is exactly the reverse order of the completion of their
> constructors?
> >>
>
> [skip]
>
> >> So, is it a must for a conforming compiler to have the output like:
> >> b ctor
> >> a ctor
> >> a dtor
> >> b dtor
> >>
> >> And not:
> >> b ctor
> >> a ctor
> >> b dtor
> >> a dtor
> >>
> >> To my great surprise some of tested compilers preferred to do the latter.
> >
> >That is clearly wrong.
> >Please tell us which compilers do that.
>
> Notorious Borland C++ 5.5 for Win32

You stated:

"To my great surprise some of tested compilers preferred to do the latter."

Which other compilers beside Borland C++ 5.5 for Win32 are incorrect ?

The interesting thing is that if the static objects are moved outside of the
functions, the order of the destructors is correct in Borland C++ 5.5 . You can
report this bug to Borland on their bug submission page. I am going to report
the bug as well.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Yaroslav Mironov" <tada@mail.wplus.net>
Date: Wed, 4 Oct 2000 06:22:53 GMT
Raw View
Hello,

Is it guaranteed that the order in which destructors of static objects are
called is exactly the reverse order of the completion of their constructors?

3.6.3/1 says:
Destructors for initialized objects of static storage duration (declared at
block scope or at namespace scope) are called as a result of returning from
main and as a result of calling exit. These objects are destroyed in the
reverse order of the completion of their constructor or of the completion of
their dynamic initialization. If an object is initialized statically, the
object is destroyed in the same order as if the object was dynamically
initialized.

Consider this code:

#include <iostream>

struct a
{
 a() { std::cout << "a ctor\n"; }
 ~a() { std::cout << "a dtor\n"; }
};

struct b
{
 b() { std::cout << "b ctor\n"; }
 ~b() { std::cout << "b dtor\n"; }
};

a &a_object()
{
 static a a_;
 return a_;
}

b &b_object()
{
 static b b_;
 return b_;
}

int main(void)
{
 b_object();
 a_object();
}


So, is it a must for a conforming compiler to have the output like:
b ctor
a ctor
a dtor
b dtor

And not:
b ctor
a ctor
b dtor
a dtor

To my great surprise some of tested compilers preferred to do the latter.

Yaroslav


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Dennis Yelle <dennis51@jps.net>
Date: 2000/10/04
Raw View
Yaroslav Mironov wrote:
>
> Hello,
>
> Is it guaranteed that the order in which destructors of static objects are
> called is exactly the reverse order of the completion of their constructors?
>
> 3.6.3/1 says:
> Destructors for initialized objects of static storage duration (declared at
> block scope or at namespace scope) are called as a result of returning from
> main and as a result of calling exit. These objects are destroyed in the
> reverse order of the completion of their constructor or of the completion of
> their dynamic initialization. If an object is initialized statically, the
> object is destroyed in the same order as if the object was dynamically
> initialized.
>
> Consider this code:
>
> #include <iostream>
>
> struct a
> {
>  a() { std::cout << "a ctor\n"; }
>  ~a() { std::cout << "a dtor\n"; }
> };
>
> struct b
> {
>  b() { std::cout << "b ctor\n"; }
>  ~b() { std::cout << "b dtor\n"; }
> };
>
> a &a_object()
> {
>  static a a_;
>  return a_;
> }
>
> b &b_object()
> {
>  static b b_;
>  return b_;
> }
>
> int main(void)
> {
>  b_object();
>  a_object();
> }
>
> So, is it a must for a conforming compiler to have the output like:
> b ctor
> a ctor
> a dtor
> b dtor
>
> And not:
> b ctor
> a ctor
> b dtor
> a dtor
>
> To my great surprise some of tested compilers preferred to do the latter.

That is clearly wrong.
Please tell us which compilers do that.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]