Sunday, January 25, 2009

Static initialization fiasco

In the example in the "Dynamic initialisation" section, the constructors for A
and B use std::cout. Is std::cout guaranteed to be available at that point?

The A and B objects in the cited example are static objects. So are
std::cout, std:cerr and std::cin. The problem is that the
order of initialization of static objects is undefined. In case there are no extra rules for the
input/output objects, the constructors of A and B indeed might use them
uninitialized.
In fact, there are no special rules for the input/output objects. Instead the standard simply
says in section 27.3

The objects [cout, cin, cerr] are constructed [...] before the body of
main begins execution.264) The objects are not destroyed during program
execution.265)

with the footnotes saying

264) If it is possible for them to do so, implementations are encouraged
to initialize the objects earlier than required.

265) Constructors and destructors for static objects can access these
objects to read input from stdin or write output to stdout or stderr.

Footnote 264 is vary vague. I interprete it like this: Strictly spoken it is not guaranteed, that
std::cout exists during the execution of constructors of static objects. But the
implementation is not forbidden to give this guarantee on its own. And I would guess that all
practically important implementations do so.
Footnote 265 is a bit confusing. Sure, you "can" use it, but there is no guarantee that it works, as
implementations are only encouraged but not forced to initialize the input/output objects betimes.
So, my answer to the question is: as far as I can see, using cout et al in constructors
of static objects is theoretically not portable. But in practise it should be a safe bet.
Platform independence is overestimated anyway!
Thanks to Michael