Uninitialized externals and statics.

Tom Karzes karzes at mfci.UUCP
Wed Aug 23 05:01:14 AEST 1989


In article <1423 at csv.viccol.edu.au> timcc at csv.viccol.edu.au (Tim Cook) writes:
>In article <1989Aug19.053711.7462 at twwells.com>, bill at twwells.com (T. William Wells) writes:
>> At one point, we got toasted by some of our customers because our
>> executables were excessively large. It seems that one of our
>> programmers did things like:
>> 
>> int     Array[1000] = {0};
>
>Let's not misappropriate blame here.  It seems to me that your compiler
>should take the blame in this scenario.  Your programmer is simply making
>sure of what will be in "Array" when the program starts (sounds like a
>worthwhile programming practice).

Actually, given that the programmer is unwilling to rely on implicit
zero initialization of statics, he/she is is only making sure that that
the first element of the array is initialized to 0 in this example.

>It's not his fault if the compiler can't sense that he has initialized it
>to the default.  Seems like a simple optimization to me.

Yes, it is a simple optimization.  However, standard Unix C compilers have
always placed explicitly initialized objects in the data section, regardless
of whether or not they're initialized with zero.  One important benefit of
this is that it permits the value in the executable to be patched with adb.
If it's in the bss section, you can't patch it in the file, and are forced
to modify and recompile the defining file, then relink the executable.
When we added this optimization to our compiler, there were so many complaints
about not being able to patch C executables that we added 2 switches to
control this behavior.  One switch forces EVERY defined object to the
data section, even if it isn't initialized at all (this is fairly extreme
and almost never used; it certainly isn't the default).  The second limits
the maximum size of an object which will be placed in the data section
when explicitly initialized with zero (the first switch overrides this
switch).  Thus, by setting the first option to FALSE and the second to,
say, 16, the behavior is to place all uninitialized objects in the bss
section, and all objects which are explicitly initialized to zero in
the data section, unless their size is greater than 16 bytes, in which
case they're placed in the bss section.  It was felt that 16 was a
conservative figure (it forces all explicitly initialized scalars,
including double complex (if you're dealing with Fortran code), into
the data section, but gives you the space savings you want when large
arrays are involved).

>(Of course, most C compilers produce assembler, so they could have a go at
>passing the buck on this one).

This is unreasonable.  If you tell an assembler to place a 0 in the
data section, it has absolutely no business trying to second guess
your intent and placing it elsewhere.  Your code could be making
all kinds of assumptions about the location of that entity.  (Besides,
in most Unix assemblers all it has is one or more labels followed
by some data; how is it supposed to know that one of those labels
is ONLY used to refer to the following chunk of zero data, and that
it will be used for nothing else, and that it can all be safely moved
elsewhere?)



More information about the Comp.lang.c mailing list