Whitesmith and static variable init.

Andrew Klossner andrew at orca.UUCP
Tue Aug 2 15:48:02 AEST 1983

To shed a bit more light on Whitesmiths C and initializations:  the
problem is unrelated to the "tricky" initialization sequence;
Whitesmiths C postdates K&R and implements arbitrarily complex
initialization as well as does any C compiler.

There are two aspects to its deviations from Unix C, concerning global
and static data.

GLOBAL:  the problem is not that some loaders don't implement .bss, but
that some loaders don't implement "common".  Consider the case in which
a program is split into two files, each of which contains the line "int x;".
In each of the two resulting *.o files, Unix cc(1) tells ld(1) that x is
"common", and that exactly one integer should be allocated.

Many loaders don't understand this notion; they require that exactly
one object module declare x to be "global" and that all others declare
it to be "external".  There is no means by which a compiler can do this
when the declaration syntax is identical and when files are compiled
one at a time.  Thus, Whitesmiths C requires that exactly one
declaration include an initializer; this becomes the "global"
declaration, and all others become "external".

One could argue that it would make more sense to require that all but
one declaration include the word "extern", as in "extern int x;".  But
consider:  if you're porting an application written in Unix cc(1) to a
Whitesmiths environment, is it easier to change one declaration per
global, or all but one declaration per global?

STATIC:  The problem is that the declaration "static int x;" OUTSIDE of
any procedure requires an initializer.  (Static declarations within a
procedure work as expected.)  If no initializer is present, x is never
created.  The reason is that there can be multiple "forward"
declarations of a static item before the actual declaration.  This
allows, for example, two mutually recursive static procedures to invoke
each other.  In early versions of Whitesmiths C, no "forward"
declaration was possible, and so the second procedure had to be global
and had to return type "int" (because it is implicitly declared to have
these attributes when the compiler sees the call in the first
procedure).  Now, all the compiler does on seeing a static declaration
without initializer is record the symbol and its attributes so that it
can be used prior to its "real" declaration.

Arguably, the compiler could search its tables at the end of the scan
and pretend that all unresolved static declarations had in fact been
declared with zero initializers.  Perhaps this behavior will appear as
part of an upgrade.

  -- Andrew Klossner   (decvax!teklabs!tekecs!andrew)  [UUCP]
                       (andrew.tektronix at rand-relay)   [ARPA]

More information about the Comp.lang.c mailing list