lifetime of function scoped statics

  • Follow


In general, automatic objects are destroyed in the opposite order that
they are constructed.  It is possible, therefore, to use an object
that has already been destroyed.

Take the following code example.  Main calls a function that creates a
function scoped static and uses it.  Main then exits, and automatic
objects are destroyed.  First, the function scoped static is
destroyed.  Next, a global object is destroyed.  This global object's
destructor calls the same function, which attempts to use the
destroyed function scoped static.

Here is my sample code:

#include <iostream>
using namespace std;

void func() {
  //function scoped static
  static struct B {
    B() { cout << 'B' << endl; }
    ~B() { cout << "~B" << endl; }
    void method() const { cout << "B::method" << endl; }
  } b;
  b.method();
}

//global object destructor calls func()
static struct A {
  A() { cout << 'A' << endl; }
  ~A() {
    cout << "~A" << endl;
    func();
  }
} a;

int main(int argc, char **argv) {
  func();
}

and my output:

A
B
B::method
~B
~A
B::method


What does the standard have to say?  Is this the correct output /
order?  The expected output?  Is it undefined?

joshua lehrer
factset research systems
NYSE:FDS

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply usenet_cpp 10/12/2004 10:30:31 PM

Joshua Lehrer wrote:
 > In general, automatic objects are destroyed in the opposite order that
 > they are constructed.  It is possible, therefore, to use an object
 > that has already been destroyed.
 >
 > Take the following code example.  Main calls a function that creates a
 > function scoped static and uses it.  Main then exits, and automatic
 > objects are destroyed.  First, the function scoped static is
 > destroyed.  Next, a global object is destroyed.  This global object's
 > destructor calls the same function, which attempts to use the
 > destroyed function scoped static.
 >
 > Here is my sample code:
 >
 > #include <iostream>
 > using namespace std;
 >
 > void func() {
 >   //function scoped static
 >   static struct B {
 >     B() { cout << 'B' << endl; }
 >     ~B() { cout << "~B" << endl; }
 >     void method() const { cout << "B::method" << endl; }
 >   } b;
 >   b.method();
 > }
 >
 > //global object destructor calls func()
 > static struct A {
 >   A() { cout << 'A' << endl; }
 >   ~A() {
 >     cout << "~A" << endl;
 >     func();
 >   }
 > } a;
 >
 > int main(int argc, char **argv) {
 >   func();
 > }
 >
 > and my output:
 >
 > A
 > B
 > B::method
 > ~B
 > ~A
 > B::method
 >
 >
 > What does the standard have to say?  Is this the correct output /
 > order?  The expected output?  Is it undefined?

Do you mean to say that you don't have a copy of the Standard yet?

The Standard says that objects with static storage duration are destroyed
after 'main' returns in the order reverse to their creation.  There is
no need for scoped statics to create undefined behaviour, you can do it
with regular global statics:

      struct A { void foo(); };
      struct B { ~B(); };
      B b;  // will be created first and deleted last
      A a;  // will be created second and deleted first
      B::~B() { a.foo(); } // accessing global object
      int main() {}

The recommendation is "don't do it".

Victor

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Victor 10/13/2004 11:42:12 AM


Joshua Lehrer wrote:

[]

> Here is my sample code:
>
> #include <iostream>
> using namespace std;
>
> void func() {
>   //function scoped static
>   static struct B {
>     B() { cout << 'B' << endl; }
>     ~B() { cout << "~B" << endl; }
>     void method() const { cout << "B::method" << endl; }
>   } b;
>   b.method();
> }
>
> //global object destructor calls func()
> static struct A {
>   A() { cout << 'A' << endl; }
>   ~A() {
>     cout << "~A" << endl;
>     func();
>   }
> } a;
>
> int main(int argc, char **argv) {
>   func();
> }
>
> and my output:
>
> A
> B
> B::method
> ~B
> ~A
> B::method
>
>
> What does the standard have to say?  Is this the correct output /
> order?  The expected output?  Is it undefined?

The behavior is correct: objects are destroyed in reverse order they were created. Functions static objects are initialized when control flow reaches their declaration for the first time. In the code object b is initialized after object a had already been initialized when you call func() in main(), so it's no surprise b gets destroyed first.



-- 
Maxim Yegorushkin

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Maxim 10/13/2004 9:19:15 PM

2 Replies
65 Views

(page loaded in 1.542 seconds)

Similiar Articles:













7/29/2012 12:53:57 AM


Reply: