Date: Sun, 15 Jan 1995 16:08:32 +0900 From: Stephen Turnbull To: cgg AT mundil DOT cs DOT mu DOT OZ DOT AU Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: C++ constructors for global vars Sorry if this message has appeared before on this list. I posted the question a few days ago, but for a variety of reasons I suspect it didn't get through. I haven't seen it before. Anyway, I'm having a problem with the order in which constructors are invoked for global C++ objects. I have two classes, say A and B, and one global object for each class: class A { public: A() {constructor code;} }; A a; class B { public: B() {do something with object a;} }; B b; Now, the problem is, I need the constructor for a to be invoked before the constructor for b (since this constructor uses object a). This is complicated by the fact that the objects are in different source files in an archive. Is there any way that I can force the above ordering? I've tried changing the order of the files in the archive, which I though might change the order in which they were linked, but this didn't help. Linking order has nothing to do with this. According to the ARM, if you want global objects' constructors called in a certain order, you must define them in that order in a single file. C++ does not allow you to (portably) enforce the order in which objects are constructed across files, because this would require new linking technology. This is considered infeasible because of the number of old systems in place and the requirement that C++ object code be link-compatible as much as possible with other languages's modules. I wrote a little test program to try and solve this problem, and found that I had to link the object files in the _reverse_ order that I wanted the constructor invoked. Unfortunately, ordering the files in the archive in the reverse order didn't work :( Just another comment about this. Do people think that the above kind of code is bad programming style? (ie. having global objects, with a requirement to have a certain ordering for the invokation of their constructors.) I do have good reasons for doing it, but I just wondered what people thought. Bjarne doesn't. He explicitly recommends it as the best way to guarantee that code that initializes external libraries gets executed and in the right order. But you must define the objects whose constructors execute the initialization code in the same file, preferably in the file with main. This is really no more difficult than including header files, and has certain advantages. It is, of course, not recommended that you put the definition in the header file: if the header file is used in more than one place, the initialization will take place twice---often with disasterous results. I, of course, worship the ground that Bjarne walks upon and would never think of disagreeing with him. (In this case, I haven't thought about the alternatives, so I'll go with the ARM :-) --Steve