davidc@vlsisj.uucp (David Chapman) (06/04/91)
The thread about static object initialization order made me go look up the discussion in the ARM. It's a good thing I did, because I'm doing some things in my code that aren't guaranteed to work! In particular, I'd like to have self-constructing tables using global objects. For example, I could define a file version class. Its constructor would get the name of the file (e.g. SCCSid), which it would then squirrel away, and add itself to the (growing) list of files. Then I could define a member function that would traverse this list, printing all of the versions *without knowing the names of the objects it is traversing*. In this way the table extends itself automatically as I add source code. As section 3.4 reads now, only the modules that have had code executed at the time I call the "print versions" function are guaranteed to have their version objects constructed. While this might be useful in telling me which code has been executed, it's not what I want. Zortech C++ prints the whole table for me now (which is why I never looked up the details in the ARM until now), but obviously I can't depend on that unless the language definition is tightened up the way I want it. I don't know how hard it is to do this in cfront (or Zortech, or BC++, etc.) but it sure would be nice. Perhaps locally defined objects not declared "static" could be assured of being constructed before main() gains control? I don't care how it looks, I just want it to work. Here's some example code (from memory; I have my actual "working" code somewhere but I can't find it right now): // declaration file (filver.hpp): class fileversion { private: const char *_ver; static fileversion *firstver; fileversion *nextver; public: fileversion(const char *ver); printallversions(void); }; // implementation file (filever.cpp): #include "filever.hpp" static fileversion::*firstver; // implicitly defined as 0; this was // the original discussion which made // me look this up fileversion::fileversion(const char *ver) { _ver = ver; nextver = firstver; // here's the self-constructing part! firstver = this; // order of construction not important } fileversion::printallversions(void) // print all file versions { // could be fancier, obviously fileversion *thisver; for (thisver = firstver; thisver != 0; thisver = thisver->nextver) printf("%s\n",_ver); } // example usage (foo.cpp): #include "filever.cpp" fileversion foofilever("File foo.cpp 1-Jun-1991"); // one of these per file ... // main program (main.cpp): #include "filever.cpp" fileversion mainfilever("File main.cpp 3-Jun-1991"); main() { mainfilever.printallversions(); // prints "foo.cpp" and "main.cpp" } I have other uses for the self-constructing tables, and they need this guarantee much more (i.e. holes in the table aren't allowed). Otherwise, I'll be forced to put all of the objects into one big file and use "extern" everywhere else. :-( Suggestions? Comments? David Chapman {known world}!decwrl!vlsisj!davidc vlsisj!davidc@decwrl.dec.com