Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ static global non-POD: theory and practice

I was reading the Qt coding conventions docs and came upon the following paragraph:

Anything that has a constructor or needs to run code to be initialized cannot be used as global object in library code, since it is undefined when that constructor/code will be run (on first usage, on library load, before main() or not at all). Even if the execution time of the initializer is defined for shared libraries, you’ll get into trouble when moving that code in a plugin or if the library is compiled statically.

I know what the theory says, but I don't understand the "not at all" part. Sometimes I use non-POD global const statics (e.g: QString) and it never occured to me that they might not be initialized... Is this specific to shared objects / DLLs? Does this happen for broken compilers only?

What do you think about this rule?

like image 455
rpg Avatar asked Oct 08 '09 14:10

rpg


2 Answers

The "not at all" part simply says that the C++ standard is silent about this issue. It doesn't know about shared libraries and thus doesn't says anything about the interaction of certain C++ features with these.

In practice, I have seen global non-POD static globals used on Windows, OSX, and many versions of Linux and other Unices, both in GUI and command line programs, as plugins and as standalone applications. At least one project (which used non-POD static globals) had versions for the full set of all combinations of these. The only problem I have ever seen was that some very old GCC version generated code that called the dtors of such objects in dynamic libraries when the executable stopped, not when the library was unloaded. Of course, that was fatal (the library code was called when the library was already gone), but that has been almost a decade ago.

But of course, this still doesn't guarantee anything.

like image 177
sbi Avatar answered Sep 21 '22 13:09

sbi


If the static object is defined in an object that does not get referenced, the linker can prune the object completely, including the static initializer code. It will do so regularly for libs (that's how the libc does not get completely linked in when using parts of it under gnu, e.g.).

Interestingly, I don't think this is specific to libraries. It can probably happen for objects even in the main build.

like image 39
Bahbar Avatar answered Sep 22 '22 13:09

Bahbar