Path: utzoo!yunexus!geac!syntron!jtsv16!uunet!seismo!sundc!pitstop!sun!decwrl!ucbvax!ulysses!hector!jss From: jss@hector.UUCP (Jerry Schwarz) Newsgroups: comp.lang.c++ Subject: Re: Summary of global constructor responses. Message-ID: <10761@ulysses.homer.nj.att.com> Date: 25 Oct 88 03:28:53 GMT Article-I.D.: ulysses.10761 References: <5964@columbia.edu> Sender: netnews@ulysses.homer.nj.att.com Reply-To: jss@hector.UUCP (Jerry Schwarz) Organization: AT&T Bell Laboratories Lines: 64 In article <5964@columbia.edu> beshers@select.UUCP (Jonathan M. Smith) writes: >I got several responses to my query about the calling order of global >constructors. Since it seems to be and important issue, I provide >a summary here. > >The problem was, I referenced 'cout' in a global constructor and >the program dumped before the first line of 'main()', indicating >that my global constructor had been called before cout's. I >compiled on a Sun4 with AT&T CC. > The situation is both more and less complicated than is suggested by most of the prior responses in this group. The C++ language definition says that the constructors for static objects are called in the order they appear in a file, but gives no assurance about what order the initialization occurs between files. The "fixes" provided manage to force particular orders in particular cases in particular versions of particular compiling systems. The are special purpose and do not really solve the problem. But a technique I have developed allows the programmer to achieve the desired effect without making any implementation specific assumptions. This technique is incorporated in the iostream package that will probably be part of cfront release 2.0 and will allow you to use iostream I/O from constructors with minimal care. I will sketch it here. I more complete description is contained in a short paper that I have written. (It hasn't been formally "released" yet, but if you send me a note I'll send you a copy when it is available.) Although it may seem complicated at first, once it is understood it can be applied without much thought. At the end of iostream.h there is a declaration of a class class Iostream_init { public: static int init_count ; // initialized to 0 Iostream_init() ; ~Iostream_init() ; } ; static Iostream_init iostream_init ; Thus the constructor for Iostream_init is called at startup once for every file that includes iostream.h. Similarly, during exit processing, the destructor is called once for every time the constructor was called. The purpose of init_count is to ensure that the real initialization and finalization actions occur only once. In particular cin and cout are initialized by the Iostream_init constructor the first time it is called. (A slight complication arises because an iostream variable cannot be explicitly initialized. An ugly kludge using the preprocessor lets me get around this.) Because of its placement in the header file the Iostream_init constructor will normally be called before any use of cout or cin. In some cases explicit calls must be inserted. My style calls for initialization classes to be associated with almost all classes I define. Explicit calls to new Iostream_init must sometimes be added in the constructors for initialization classes. In particular, when a constructor of class K does I/O, but the header associated with class K does not require iostream.h to be included before the declaration of K, then a call to "new Iostream_init" must appear in the constructor of K_init before the use of any K constructor. Jerry Schwarz AT&T Bell Labs, Murray Hill