Path: utzoo!utgpu!water!watmath!clyde!rutgers!gatech!hao!ames!amdahl!dlb!megatest!djones From: djones@megatest.UUCP (Dave Jones) Newsgroups: comp.lang.c++ Subject: Re: Ordering of initialisation of static classes in *different* files ? Message-ID: <218@goofy.megatest.UUCP> Date: 18 Jan 88 03:00:00 GMT References: <734@hslrswi.UUCP> Organization: Megatest Corporation, San Jose, Ca Lines: 71 in article <734@hslrswi.UUCP>, robert@hslrswi.UUCP (J. Robert Ward) says: > > Hello C++ Gurus, > > It seems to me that there is a (small) defect in the definition of > the C++ language. Namely, the order in which static objects are > initialised is apparently undefined when more than one source file > is under consideration. > ... > Question: how can I guarantee that cout is properly initialised > by its constructor before it gets passed as an argument to [a constructor for a global object]? Answer: I don't think you can. > The problem came about in trying to solve question 12 on page 167 > of the C++ book. Can this problem really be solved assuming I am > not allowed to change main() in any way ? If by "neatly" you mean "using cout", I don't think so. It seems unfortunate that cout requires a constructor to be called at startup time, but it does. The same is true of cerr. I expect this to be the source of lots of botched error-messages from constructors. You will not have such problems with fprintf() and write(). It's a little ironic that the requirement that a constructor be called is the cause of using uninitialized data, since constructors were intended to prevent just that from happening. On page 289, it says "Constructors for non-local static objects are called in the order they occur in a file...". I find nothing about ordering of constructor calls for objects declared in separate files. A little thought will convince you that it would be a non-trivial job to assure proper order of construction. In the case at hand, the object "cout" is declared in the C++ library. So where is its "occurance" in the PROGRAM? At the first spot at which it is declared "extern", I suppose. That is to say, at the first #include . But "munch", the program which builds the constructor-caller routine, has no knowlege of where that might be. So, in constructors, use fprintf() or write(), not cout and cerr. Or you can build your own ostream, if you just HAVE to: #include class sic_transit { public: sic_transit() { filebuf fileout(stdout); ostream myout(&fileout); myout << "I be.\n"; } ~sic_transit() { filebuf fileout(stdout); ostream myout(&fileout); myout << "I be history.\n"; } }; sic_transit gloria_mundi; main() { cout << "Hello, world.\n"; }