On 2009-01-14 17:05:06 -0500, James Kanze <
[email protected]> said:
[...]
In practice there is, and in C++0x it's required.
I don't think so (and it's never been guaranteed). The only
thing I find in the CD is "If a translation unit includes
<iostream> or explicitly constructs an ios_base::Init object,
these stream objects shall be constructed before dynamic
initialization of non-local objects defined later in that
translation unit." ([iostream.objects]/2). And in the example
above, the conditions of the if aren't met---unit2.cc doesn't
include <iostream> (since it does no IO), so there's no
guarantee that cout will have been constructed before the
constructor a aStaticC is called.
This isn't new---it was a known problem back in the days of
CFront. CFront more or less masked it by initializing the
translation units in the reverse of the order they were
incorporated into the final executable. Since cout et al. were
in a library which came normally at the end of the link process,
after all user libraries and object files, they would be
initialized first.
FWIW: I just compiled the above with g++ (changing "class" to
struct so that the constructor was accessible, and adding an
empty main()). If I compile with "g++ unit2.cc unit1.cc", no
problem, but "g++ unit1.cc unit2.cc" core dumps before entering
main. Both Sun CC and VC++ work both ways, but historically, I
don't believe it was ever guaranteed---I'm pretty sure I
remember something in the CFront documentation saying that it
wasn't. And unless I'm missing something, it's not guaranteed
even in C++0x.