Mail Archives: djgpp/1994/12/08/22:26:46
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
- Raw text -