I have previously posted a fairly detailed summary of what the C++
standard says about when static objects are created/initialized, which
you can find athttp://preview.tinyurl.com/2rsal2. I'd be interested
if there are parts of the standard not mentioned in that post which
support your statement, particularly the "before anything executes"
and "well before main" comments.
You quote the relevant passage in your posting. Initialization
is in the order: zero initialization, static initialization
dynamic initialization. Note in particular the first sentence
of §3.6.2: "Objects with static storage duration (3.7.1) shall
be zero-initialized (8.5) before any other initialization takes
place." Before, for example, the argc and argv arguments to
main are initialized, as well as before any dynamic
initialization of static objects.
I think my original post does not sufficiently address the
situation of a POD type initialized with a constant expression
and I would like to fill in the gaps.
You're post really neglects reality. The constraints that the
standard imposes if dynamic initialization is deferred until
after main are impossible to meet, and no implementation tries.
(Dynamic linking may open up another can of worms, but what
happens then is implementation defined anyway---although most
systems behave identically here as well.) From a practical
point of view, it's safe to say: zero initialization, then
static initialization, then dynamic initialization, then main.
With the first occasion for your code to run being dynamic
initialization (which means that the zero initialization of
statically initialized objects isn't visible, and may be
skipped).
There's also, of course, the fact that many, many idioms depend
on dynamic initialization before main, and that any compiler
which tried to do otherwise simply wouldn't be used.
If you exclude dynamic linking, it's really fairly simple. If
you don't start any threads before entering main, that means
that threading issues aren't involved either.