[net.lang.c] Multiple external definitions

guy@rlgvax.UUCP (Guy Harris) (03/04/85)

>  The section 7.2 External data definitions of "Draft proposed C standard"
>  indicates that you CAN omit "extern". When the standard gets acceptance,
>  I do not think argument "standard is not the whole world" will be sufficient
>  reason to "play tricks" just to be able to compile on some nonconforming
>  C compiler.

However, in E.5.4 "Common extensions", it says:

	     The following extensions are widely used in many systems,
	but are not portable to all implementations.

	...

	E.5.4.6 Multiple external definitions

	     There may be more than one external definition for
	the identifier of an object, with or without the explicit
	use of the keyword "extern" ...

Making this a "common extension" would be pointless if all C implementations
were expected to support multiple external definitions.  In fact, not all
do; it is a royal pain (possibly impossible) to implement multiple external
definitions on most non-UNIX linkers.  It's not a question of the C compiler;
there's not much the C compiler can do about it.

C.7.2 "External data definitions" says that multiple external definitions
can occur *in the same source file*; this can be handled by the compiler,
so the fact that the linker doesn't support this doesn't matter.

A lot of this debate seems to have been caused by misunderstandings of
people's comments and/or misstatements of history.  A quick clarification
of some points:

All UNIXes prior to System V supported multiple external definitions.
The linker introduced in System V Release 1 did not (either that, or
the original one did but it was withdrawn).  The idea was nice in principle
(catch programs that wouldn't build on non-UNIX systems before they got
moved to those systems), but was done too suddenly.  When Dennis introduced
the "+=" type of operator he didn't immediately withdraw support for "=+" type
operators.  It might have been better to just have warnings issued for
multiple external definitions and withdraw support for them in a later
release, in order to give people time to adapt to the new regime.

Contrary to what one poster indicated, it's *not* Berkeley's fault that
multiple external definitions are supported in BSD UNIX.  That goes all
the way back to V6 and probably much further.

AT&T did not do an Evil Thing and thumb their nose at the rest of the world
by putting support of multiple external definitions back into System V in
Release 2.  They responded to the screams of pain caused by peoples' code
breaking suddenly; admittedly, one could argue that "they should have read
K&R better" (lots of us do write code without using multiple external
definitions) but dropping it on people suddenly probably wasn't the wisest
thing to do.  (It may not have been sudden outside Bell, but I don't think
they warned people in advance before announcing System V.)

They do support a flag ("-M", I believe) to warn the user of multiple external
definitions. I would vote for gradually withdrawing support for them; they
don't add any real functionality (any code that uses them can be rewritten not
to use them), and they can trap people into writing non-portable code.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy
-- 
	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

bsa@ncoast.UUCP (Brandon Allbery) (03/08/85)

> Article <551@rlgvax.UUCP>, from guy@rlgvax.UUCP (Guy Harris)
+----------------
| All UNIXes prior to System V supported multiple external definitions.

Our Xenix system, however, doesn't, for all that it was developed from V7
source.  Lots of programs fail spectacularly on my terminal (including the
editor I'm using to type this in), because my terminal requires padding
and almost every termcap-using program we get has "int ospeed;" in it
(we need "extern short ospeed;", also outlining a certain size dependency...

--bsa
-- 
Brandon Allbery, decvax!cwruecmp!ncoast!bsa, ncoast!bsa@case.csnet (etc.)
6504 Chestnut Road Independence, Ohio 44131 +1 216 524 1416 -- CIS 74106,1032
		 -=> Does the Doctor make house calls? <=-

guy@rlgvax.UUCP (Guy Harris) (03/12/85)

> > All UNIXes prior to System V supported multiple external definitions.
> 
> Our Xenix system, however, doesn't, for all that it was developed from V7
> source.  Lots of programs fail spectacularly on my terminal (including the
> editor I'm using to type this in), because my terminal requires padding
> and almost every termcap-using program we get has "int ospeed;" in it
> (we need "extern short ospeed;", also outlining a certain size dependency...

If your program links without complaint, then your Xenix supports multiple
external definitions.  If it only fails on your terminal, it must have linked
without complaint in order to run on another terminal.  The problem you're
describing is a separate problem; externals in UNIX behave like FORTRAN
common blocks, in that externals have a size, and if you have several
declarations of the same external with different sizes, the biggest one
wins.  If your machine has 32-bit "int"s, and it's big-endian (like a
68000 with 32-bit "int"s), then one declaration as a "short" and one
declaration as an "int" won't work (references to the "short" will pick up
the *upper* 16 bits of the "short", which will be zero, and thus give no
padding).  (If your machine is little-endian, it's *still* wrong, but
symptomless in this particular case.)
-- 
	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy