[net.lang.c] Whitesmith and static variable init.

rck@ihuxm.UUCP (07/15/83)

I've had some experience with Whitesmith's C compiler and support tools.
Unfortunately, their variable initialization does not follow the accepted
standard, but they don't have much of a choice.  The Whitesmith package
is designed for use on small "operating systems" like CP/M.  CP/M does
not support any kind of runtime loader that zeroes a program's bss
section, so apparently Whitesmith's has taken the approach of forcing
all statics to be initialized in order to force them into the data
section of the program.  So in this way, the initialized variables, be
they scalar or array, are part of the program image and are copied in
when the program is run.  I don't know why Whitesmith's just didn't put
ALL statics into the data section, even if they weren't explicitly
initialized.  Maybe someone else could respond.
						Ron Kukuk
						Bell Labs
						Naperville

sanand@hcr.UUCP (Sanand Patel) (07/20/83)

A possible reason that all variables must be explicitly initialized is
due to the fact the White* compilers often generate assembler code
for various (non-un*x) operating systems. The assembled code
is then run through the native (non-white*) assemblers and linkers.
I suppose that not all assemblers and loaders know how to figure out
when to assign storage to these kinds of variables.

{decvax|linus}!utzoo!hcr!sanand

tom@rlgvax.UUCP (07/23/83)

I can't buy the arguments that Whitesmith compilers force explicit declarations
in all external definitions because some linkers don't support "bss space"
(space that is "stored" in the object module only by a mention of how
long it is -- once a loader loads the program it is supposed to allocate
that much space and zero it out).

If you can't use "bss space", don't!!
Just build into the compiler that any external definition not explicitly
initialized is implicitly initialized to 0.  On machines that support
"bss", set up the "bss" space in your compiler output.  On machines that
don't, simply include these with your initialized variables, except that
they happen to be initialized to 0.  Use of a "bss" feature is independent
of the input language.  Why do you thionk they call it "high level" ...

My guess is that Whitesmith's found it difficult and/or inconvenient
to implement C's initialization syntax.  One reason may be that originally,
C did not use a "=" between the variable name and the initialized value,
so constructs like "int x 5;" were allowed.  This got pretty difficult
to implement when fancier initializations were allowed (things like
structure initialization got added), so Bell Labs added the "=" to make
life easier.  Whitesmith's perhaps got caught before or during the change.

Another reason may be that they share quite a few components between
compilers of different languages, and doing proper C initialization was
difficult to do with their tools and components.  So they decided to
change the product instead of sharpening the tools.

If anyone knows the real reason I'd be interested to know ...
- Tom Beres
{sesimo, allegra, , mcnc, brl-bmd}!rlgvax!tom

sanand@hcr.UUCP (Sanand Patel) (07/27/83)

You can't just initalize every un-initialized external variable to zero,
because multiple module (file) programs would result in 
multiple declarations (in the assembly code)
for variables mentioned in more than one file ...

andrew@orca.UUCP (Andrew Klossner) (08/02/83)

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@rand-relay)   [ARPA]