Initialization of static data is more problematic than you think; it's particularly susceptible to races.
On the other hand, there are very important pragmatic reasons for using 0 to initialize data; the OS loader can give you zero pages (corresponding to bss segment or equivalent) for "free"; free to the point that they don't need to be stored in the image, and allocated lazily as needed.
It is also guaranteed in C++11. GCC has been implementing thread-safe initialization since version 4, I believe, but I'm not sure whether they use this algorithm.
That doesn't solve anything relevant; I quote, "the initialization of an object is indeterminately sequenced with respect to the initialization of an object defined in a different translation unit"; if you have two pieces of initialization code in different translation units, each referring to the other's data-to-be-initialized, you have a race; one is going to get initialized first (whether the order is determined by the standard, by the link order, by the arbitration of dragons, it doesn't matter) and the other is going to be uninitialized when accessed.
I personally think it's better, where possible, to define the relevant types such that a zeroed structure as a valid state, or else use trivial initialization (where "trivial" might be defined as literals or constant expressions). Where this is not possible, explicit initialization (e.g. called directly or indirectly from main()) ought to be used.
Wait, I think we are talking about two different things: the spec I pointed to refers to static local variables, and solves pretty much all the cases I can think of. (Initialization is delayed until first function call).
You are talking about global static variables, and yes, that's a tricky matter.
Well, being local doesn't protect you from indirect access; it's the lifetime that makes statics troublesome, not the scope. The function wrapping the local may be called by the initialization.
On the other hand, there are very important pragmatic reasons for using 0 to initialize data; the OS loader can give you zero pages (corresponding to bss segment or equivalent) for "free"; free to the point that they don't need to be stored in the image, and allocated lazily as needed.