Explicitly destroying a non-pointer static object
I'm working with the Autodesk Maya api, and the MLibrary::cleanup
function "...prevents any static destructors from being executed." source
The code that uses the Maya api also uses some of my dlls which contain non-pointer static variables that need to be destroyed (specifically, a Log class which contains a static Log stdLo开发者_StackOverflow中文版g
, that needs to write a footer and close the file stream).
What is the appropriate way of handling this? I've added a Log::destroy()
function which calls stdLog.~Log();
, is this safe?
Maybe it's safe, maybe not. It's better to structure the code so that it doesn't matter. Instead of having destroy
call ~Log
, have ~Log
call destroy
. Also have destroy
check to see if the object is already destroyed; add a boolean variable to track this if you must.
I would move static objects into heap objects and would add a call to allow clean shutdown. If you explicitly call a destructor on a non-dynamic object then in case of a normal program termination the destructor will be called twice and this is IMO bad.
Using an explicit shutdown call could handle correctly both cases (i.e. normal termination without shutdown and normal termination after explicit shutdown).
By the way having "complex" static instances is in my experience a problem in general because you cannot control exactly when they are created and when they are destroyed. If construction or destruction can possibly fail for any reason then for sure using those objects as static duration instances means you are looking for troubles.
Also in my experience debugging of problems that happen before the first instruction of main
or after it returned is even harder than normal debugging (e.g. a segfault that happens during program shutdown in windows is quite often silenced by the OS, and debugging before the start of main may not work as expected).
Over the years I've moved from lazy initialization/destruction to a controlled deterministic approach to startup/shutdown (if that's possible) and I'm not looking back.
If the destructor of your stdLog
is really never called, then yes, it is safe.
You could get your "Static Storage Duration" objects to register atexit()
or on_exit()
cleanup methods as part of construction and do nothing during destruction.
Then the methods registered can do the cleanup you need (such as print the footer on the log).
精彩评论