[net.unix-wizards] ULTRIX linker bug???

jwp@uwmacc.UUCP (Jeffrey W Percival) (10/09/86)

I tracked down a bug in a big program I have, but was
a little surprised with what I learned.  My program looked like this:

float x;
float y;
main()
{
...
}

Now, in /usr/lib/liblocal.a, there is a subroutine whose source file
looks like this:

double x;
double y;
sub()
{
	y = 10.0;
	print y
	x = expression;
	print y
}

I linked it with "cc main.o -llocal -o main"

Much to my surprise, the value of y was changed from 10.0 to 0.0
as a result of the assignment to x.  I thought (perhaps mistakenly)
that the scope of a variable declared at the beginning of a file
extended only throughout that file.  Even if that is not true,
shouldn't I have gotten a "multiply declared" message?

I tried bringing sub.o into my directory and typing "cc main.o sub.o"
and got the expected "multiply declared" complaint.
-- 
	Jeff Percival ...!uwvax!uwmacc!sal70!jwp or ...!uwmacc!jwp

chris@umcp-cs.UUCP (Chris Torek) (10/18/86)

In article <336@uwmacc.UUCP> jwp@uwmacc.UUCP (Jeffrey W Percival) writes:
>float x;
>float y;
>main()
>{
>...
>}
>
>[with a library] subroutine whose source file looks like this:
>
>double x;
>double y;
>sub()
>{
>	y = 10.0;
>	print y
>	x = expression;
>	print y
>}
>
>I linked it with "cc main.o -llocal -o main"
>
>Much to my surprise, the value of y was changed from 10.0 to 0.0
>as a result of the assignment to x.  I thought (perhaps mistakenly)
>that the scope of a variable declared at the beginning of a file
>extended only throughout that file.

No.

>Even if that is not true, shouldn't I have gotten a "multiply
>declared" message?

Not in the Ultrix compiler.  The Ultrix compiler uses the `common
model', where any number of `<type> x' declarations may appear, as
long none are initialised.  Exactly one initialisation is also
legal.  (Some compilers use the `def/ref model', in which all but
one declaration must be `extern'.)

Moreover, in the `common model', the size of the data space allocated
to a variable is determined by the *largest* declaration.  For example,
linking the compiled files

	x.c: char a[10];	y.c: char a[100];

produces an a.out wherein `a' holds 100 bytes.  Since strict type
checking is provided only by lint, the linker also does not care
if it is fed mismatched types as well:

	x.c: char a[10];	y.c: double a[10];

This results in an 80 byte `a' on a Vax.  Within x.c, these 80
bytes are believed to be characters; within y.c, they are believed
to be doubles.  Assigning 3.4 to a[1] in y.c clobbers a[8] through
a[15] in x.c.

>I tried bringing sub.o into my directory and typing "cc main.o sub.o"
>and got the expected "multiply declared" complaint.

But what was `multiply declared'?  x?  y?  sub?  Something entirely
different?  Teledebugging is tricky, but I doubt the Ultrix linker
was at fault.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu