Recently I got an email with the following question to the C++ and the linker article:
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
No comments:
Post a Comment