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