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: Linking to zlibstat.lib and still unresolved functions - comp ...Static Linking Problem - comp.unix.programmer... built ... unix.programmer ..... these values change during the life of the program or are the shared library function ... Dot notation in struct - comp.lang.c... type) found in a struct in a driver module: static ... In real life, of course, the C90 standard is still ... Looking for function or technique - comp.lang.rexx Reply to ... Using thread-specific data in shared libraries - comp.programming ...The function was well > intended, but poorly conceived and ... be linked to the process exe and therefore to have the lifetime of the process? Do you support static ... Accessing "Target Name" Bootline Parameter - comp.os.vxworks ...I'm sure it's something simple, but for the life of me ... Just a quick followup: this function did the trick, but it ... comp.databases ... > > > Test case name will be a static ... Passing va_list by reference to a function - comp.lang.c ...Damn the living - It's a lovely life. I found out what ... The xprintf() function looks like this static int xprintf(struct callback *cp, const char *fmt ... Explanation needed for const int "error: variably modified ... at ...A macro definition is not scoped; it remains visible ... if r can change but it doesn't -- not during the lifetime ... Integer := Random(42); It uses the word "static" to ... Bad use of stringstream temporary? - comp.lang.c++The operator<< that takes a void* is a member function ... references (or pointers), keeping an eye on the lifetime ... use of stringstream temporary? - comp.lang.c++ Static ... Detecting Extended Desktop - comp.lang.clipper.visual-objects ...... the scoreboard one, store the setting and then re-use it for the lifetime oof ... hHDC, NULL_PTR, @EnumMonitorsProc(), 0u ) ENDIF RETURN hMonitor STATIC FUNCTION ... writing robust software? - comp.lang.c++.moderated... for C++, like SPARK Ada? > search for "c++ static ... this > concept, it is very useful, I use it for function ... does have an infinite leak and one where the the life ... Result of Exception in constructor and destructor !! - comp.lang ...The object's lifetime only begins when the constructor ... Global static destructors called when a dynamic library ... Hi, I'm a testng a function func(), a member function of ... Scope (computer science) - Wikipedia, the free encyclopediafunction square (n) {return n * n;} function sum_of ... but descendants of dynamically scoped languages often adopt static scoping ... are defined to create bindings whose lifetime ... Static (C++) - Microsoft Corporation: Software, Smartphones ...A variable declared static in a function retains its state between calls to that function. ... Objects and variables defined outside all blocks have static lifetime and ... 7/29/2012 12:53:57 AM
|