Does C++ call destructors for global and class static variables?
From § 3.6.3 of the C++03 standard:
Destructors (12.4) 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 (18.3). 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. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the sub- objects is destroyed.
Furthermore, § 9.4.2 7 states:
Static data members are initialized and destroyed exactly like non-local objects (3.6.2, 3.6.3).
However, if a destructor has no observable behavior, it may not be invoked. Terry Mahaffey details this in his answer to "Is a C++ destructor guaranteed not to be called until the end of the block?" .
Why destructor of global static variable is not called?
Why would the destructor get called ? You're not deleting the object. In other words, you have a memory leak.
You could fix this by including this in the end of main()
:
delete pSingletone;
You would have to make B::~B()
public, though.
Destruction of static member in a class with global instance
First,
bool dummy = MyClass::InitStaticMember(); // m_object is initialized here
Doesn't actually intialize the static member. That happens at the line before
SomeObject MyClass::m_object;
So since you essentially have
SomeObject MyClass::m_object;
MyClass g_my_global_class;
and since objects are destroyed in the reverse order then g_my_global_class
is destroyed before MyClass::m_object
.
Now, if you move MyClass g_my_global_class;
to a different translation unit then all bets are off. The ordering is only guaranteed in a single translation unit.
Will (global) static variables be destroyed at program end?
The destructors of file or namespace scope objects get called when the control flow leaves main()
.
If an exception leaves main()
then it's implementation defined whether the destructors of any objects get called. With modern compilers the destructors won't be called in this case to allow easy inspection of the program state when the unhandled exception was thrown. Early C++ implementations used exception mechanism based on setjmp
/longjmp
which would unwind the stack while searching for the exception handler and hence calling destructors even if no suitable exception handler was eventually found.
If an application terminates with _exit()
or _Exit()
or std::quick_exit()
no destructors get called.
Static global structure's destructor not being called
I was running the above program as part of a Google test that exits main by a call to _exit()
. And it seems that destructors for static global objects aren't called when a program is terminated by a call to _exit()
. See this answer and this
what is the destruction order between global object and static variable?
Standard section 3.8 says:
The lifetime of an object of type
T
ends when:
if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
the storage which the object occupies is reused or released.
Now int
is not a class type, and since Array::counter
has static storage duration, its storage is never released. So the lifetime of Array::counter
never ends, and you can safely access it from any destructor you want!
Destructor of a global static variable in a shared library is not called on dlclose
There is no guarantee that unloading (destructors are invoked) happens on dlclose. On musl (as opposed to glibc), constructors only run the first time a library is run, and destructors only run on exit. For portable code, dlclose cannot be assumed to unload the symbols immediately.
The unload behavior depends on glibc's symbol binding when doing dynamic linking, and is independent of GCC.
The static variable get::i
has a STB_GNU_UNIQUE
binding. For static variables in inline functions, the uniqueness of the object is assured by the ELF linker. However, for dynamic loading, the dynamic linker assures uniqueness by marking the symbol STB_GNU_UNIQUE
. Hence, another attempt to dlopen the same shared library by some other code will lookup the symbol and find that it is unique and return the existent one from the unique symbols table. A symbol with unique binding cannot be unloaded.
Unique binding can be disabled with -fno-gnu-unique
if not needed.
References
Bug that I raised to GCC
STB_GNU_UNIQUE
Destructor called twice with static object
why is this happening?
Because the variable is declared static
. This means that the variable has internal linkage. Which means that each translation unit has their own object. You have defined the variable in two translation units, and therefore you have two objects.
If you didn't want this, then the variable shouldn't be static
. An easy solution is to declare it inline
instead. This allows it to have external linkage while still being defined in the header.
P.S. Be very careful of Static Initialisation Order Fiasco. Try to avoid variables of static storage when you can, especially those in namespace scope.
are C++ static variables always destructed on main thread?
Destructors of the global objects are called by std::exit
. That function is called by the C++ run-time when main
returns.
It is possible to arrange for std::exit
to be called by a thread other than that which entered main
. E.g.:
struct A
{
A() { std::cout << std::this_thread::get_id() << '\n'; }
~A() { std::cout << std::this_thread::get_id() << '\n'; }
};
A a;
int main() {
std::thread([]() { std::exit(0); }).join();
}
Outputs:
140599080433472
140599061243648
Showing that one thread called the constructor and another the destructor.
See std::exit
and std::atexit
for more details.
How are the private destructors of static objects called?
Section 3.6.3.2 of the C++03 standard 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.
It doesn't give any restriction regarding having a private destructor, so basically if it gets created it will also get destroyed.
A private destructor does cause a restriction on the ability to declare an object (C++03 12.4.10)
A program is ill-formed if an object of class type or array thereof is declared and the destructor for the class is not accessible at the point of declaration
but since the destructor of A::theMainInstance is accessible at the point of declaration, your example should have no error.
Related Topics
C++ Force Std::Cout Flush (Print to Screen)
Createprocess from Memory Buffer
Is There a Reason to Call Delete in C++ When a Program Is Exiting Anyway
Difference Between (Type)Value and Type(Value)
What's Your Favorite Profiling Tool (For C++)
How to Write a Range Pipeline That Uses Temporary Containers
Comparing Iterators from Different Containers
How to Use Reference Parameters in C++
Why Function Template Cannot Be Partially Specialized
The Differences Between Initialize, Define, Declare a Variable
Does Mingw-W64 Support Std::Thread Out of the Box When Using the Win32 Threading Model
How Do Conversion Operators Work in C++
Overload Resolution Between Object, Rvalue Reference, Const Reference