Date: Thu, 8 Dec 94 09:13 PST From: jdp AT polstra DOT com (John Polstra) To: djgpp AT polstra DOT com Subject: Large g++ object files: solution I've seen several postings here referring to the "bug" in g++ that causes uninitialized variables such as: char buf[32768]; to be placed in the data section rather than in COMMON. This makes object files and executables very large, and people have been complaining about it. I just want to point out that (a) g++ does this on purpose, and (b) there is a compiler option to make it do what you want it to do. The compiler option is "-fconserve-space". It was introduced in version 2.6.0, which means that it is available in the compiler that comes with djgpp112. From the GNU documentation, under "Options Controlling C++ Dialect": =============================================================================== `-fconserve-space' Put uninitialized or runtime-initialized global variables into the common segment, as C does. This saves space in the executable at the cost of not diagnosing duplicate definitions. If your program mysteriously crashes after `main()' has completed, you may have an object that is being destroyed twice because two definitions were merged. =============================================================================== You have to be careful if you use this option. With it, you can violate the C++ "one definition" rule, and that won't be detected at link time. For example, suppose that in a header file you declare a global instance of some class that has a constructor and destructor: class Big { public: Big(); ~Big(); private: char data[32768]; }; Big theBig; // With "-fconserve-space", this will go into COMMON Now if you include the header file in several ".cc" files and link them together, you'll get just a single instance of "theBig", in COMMON. But that instance will get constructed and destructed multiple times -- i.e., once per ".cc" file that included the header file. That is because you have broken the "one definition" rule, and the linker (because of "-fconserve-space") wasn't able to detect it. To make sure this doesn't happen, you need to arrange things so that your program contains one and only one non-extern declaration of every global variable. One way to do that is like this. In your header file, say, "global.h", declare your global variables like this: #ifndef COMMON // { #define COMMON extern #endif // } COMMON Big theBig; COMMON Big anotherBig; COMMON char buffer[18000]; You can include "global.h" in as many of your modules as you wish; all the declarations will have "extern" in front of them, and everything will be OK. Now make one special module, say "global.cc" whose purpose is to *define* the global variables. That file should look like this: #define COMMON // empty #include "global.h" (You don't HAVE to do this in a special module. You could also do it, say, in the module that contains your main() function.) It's really worth it to browse the compiler documentation. There are options out the wazoo to control just about everything you'd like to control. John Polstra jdp AT polstra DOT com John D. Polstra & Co., Inc. Phone (206) 932-6482 Seattle, Washington USA Fax (206) 935-1262 "Self-knowledge is always bad news." -- John Barth