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]