One legal implementation of destructors of static objects is to register
them with atexit
when the constructor has finished. The standard
requires the order to be the same as if this implementation was used.
The main difference is that the destructors of static objects are
destructors: they will be called automatically if the object is
completely constructed, without any necessity on your part to register
them. And they have a this
parameter to access the object.
EDIT:
To make it perfectly clear: given
T obj; // where obj has static lifetime...
The compiler would generate a function:
void __destructObj()
{
obj.~T();
}
and the following initialization code:
new (&obj) T;
std::atexit( __destructObj );
This regardless of the scope of obj
; the same basic code works for
both local statics and objects at namespace scope. (In the case of
local objects, the compiler would also have to generate a flag and code
to test it to indicate whether the object had already been initialized;
it would also have to take steps to ensure thread safety.)
It is, in fact, difficult to see how the compiler could do it otherwise
(although it might generate code inline to do what std::atexit
does),
given the ordering requirements.