This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/48323] New: Lifetime of local variables: global versus member function
- From: "j.v.dijk at tue dot nl" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 28 Mar 2011 20:01:00 +0000
- Subject: [Bug c++/48323] New: Lifetime of local variables: global versus member function
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48323
Summary: Lifetime of local variables: global versus member
function
Product: gcc
Version: 4.5.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: j.v.dijk@tue.nl
[First presented on gcc-help. Submitted as per the suggestion of Ian Lance
Taylor, see http://gcc.gnu.org/ml/gcc-help/2011-03/msg00340.html ]
Consider the following shared object:
// g++ -o libtest.so -shared -fPIC dltestlib.cpp
#include <iostream>
int global_f() { static int i=0; return i; }
struct C
{
int class_scope_f() { static int i=0; return i; }
C()
{
global_f();
// class_scope_f(); // CULPRIT
}
~C() { std::cout << "Destructor called" << std::endl; }
};
static C c;
Also consider the following test program, which merely loads and unloads this
library using dlopen/dlclose.
// g++ dltest2.cpp -ldl
#include <dlfcn.h>
#include <iostream>
int main(int argc, const char* argv[])
{
if (argc!=2) return -1;
const char* fname = argv[1];
std::cout << "Opening: " << fname << std::endl;
void* handle = dlopen( fname, RTLD_NOW | RTLD_LOCAL);
std::cout << "Handle after dlopen: " << handle << std::endl;
if(!handle)
{
std::cout << dlerror() << std::endl;
}
dlclose(handle);
// do not load. Only check if the file is resident.
handle = dlopen( fname, RTLD_NOW | RTLD_NOLOAD);
std::cout << "Handle after dlclose: " << handle << std::endl;
std::cout << "Exiting..." << std::endl;
}
Providing the abovementioned library as argument, I get the expected result:
./a.out /home/jan/src/gum-cvs/ideas/jan/libtest.so
Opening: /home/jan/src/gum-cvs/ideas/jan/libtest.so
Handle after dlopen: 0x602050
Destructor called
Handle after dlclose: 0
Exiting...
In particular, the library *is* unloaded by dlclose (so the global destructor
of object c in the library is called before the program is exiting.)
And now for the problem...
If I comment in line 11 of the library module (marked CULPRIT), thus calling
class_scope_f(), and try again, the result is:
Opening: /home/jan/src/gum-cvs/ideas/jan/libtest.so
Handle after dlopen: 0x602050
Handle after dlclose: 0x602050
Exiting...
Destructor called
Now the library unloading fails (the handle is still !=0, and indeed the
destructor of c is not called before the program terminates).
I assume this is because there is a difference in lifetime between local
static variables in functions in global scope vs. those of member functions.
Is this the intended behaviour? (I say 'intended', not 'mandated', because I
know so's are beyond the scope of ISO-C++.) If not, should I file a report?
I am on OpenSuSE 11.4; that is: glibc 2.11.3, gcc 4.5.1, binutils 2.21.