lms@uts.amdahl.com (Linda Sorauf) (05/24/91)
I have a question regarding using cout in constructors of static objects. I hope I can word the question clearly.... Basically, I have been warned against using cout in constructors of static objects. Apparently, cout, which is itself not static, relies on a static object called iostream_init. The danger is that the order of static object construction may be such that cout is used before iostream_init has been constructed. Can someone explain to me 1) is this even true, should I avoid using cout in constructors of static objects? 2) if so, why? 3) how can I create a test case where this failure happens? I have tried every sort of file and include arrangements I can think of, but cannot create such a failure. I am quite sure that I have been able to use cout before iostream_init is constructed, but in my simple programs, things seem to work fine. Thanks in advance, Linda Sorauf lms@uts.amdahl.com UTS CASE development Amdahl Corp. -- - - - - - - - - - - - - Linda Sorauf lms@uts.amdahl.com #include <std.disclaim.h>
steve@taumet.com (Stephen Clamage) (05/25/91)
lms@uts.amdahl.com (Linda Sorauf) writes: >Basically, I have been warned against using cout >in constructors of static objects. Apparently, >cout, which is itself not static, relies on a >static object called iostream_init. The danger >is that the order of static object construction >may be such that cout is used before iostream_init >has been constructed. There is a general problem with constructors of static objects referring to other objects. There is no way to guarantee the order of such constructors when they occur in different compilation units. (No portable way, at least.) With this in mind, iostreams were carefully designed to guarantee that the standard streams are all initialized before any user-defined objects are constructed, PROVIDED that you #include <iostream.h> (or some file which includes it, such as <fstream.h> or <strstream.h>) ahead of any static object which needs to use a standard stream. Example 1 (all in one file) will always work: #include <iostream.h> class C { public: C(); // ... }; C c; C::C() { ... cout << "hello\n"; } Example 2 (all in one file) will compile and link, but may or may not work: class C { public: C(); // ... }; C c; #include <iostream.h> C::C() { ... cout << "greetings from C\n"; } Example 3 (two files) will compile and link, but may or may not work: file1.c: class C { public: C(); // ... }; C c; file2.c: #include <iostream.h> C::C() { ... cout << "greetings from C\n"; } Examples 2 and 3 will work if by chance cout gets constructed before the constructor for c gets called. You cannot in general predict whether this will happen. You can make Example 2 work by moving the include to the top of the file. You can make Example 3 work by including <iostream.h> in file1.c. -- Steve Clamage, TauMetric Corp, steve@taumet.com
davew@panache.cs.umd.edu (David G. Wonnacott) (05/25/91)
In article <746@taumet.com> steve@taumet.com (Stephen Clamage) writes: >With this in mind, iostreams were carefully designed to guarantee >that the standard streams are all initialized before any user-defined >objects are constructed, PROVIDED that you #include <iostream.h> (or >some file which includes it, such as <fstream.h> or <strstream.h>) >ahead of any static object which needs to use a standard stream. I believe this works with AT&T's iostream library, but not with the stream library distributed with G++. -- David Wonnacott davew@tove.cs.umd.edu Although the moon is smaller than the earth, it is further away.