[comp.sys.ibm.pc] MSC multiple-definition bug or feature?

rhb6@bunny.UUCP (Robert H. Barkan) (10/20/88)

In MSC 5.x, compile the following 2 files, then link x1.obj and y1.obj.
The linker should complain because "int x" is multiply defined:

file x1.c:                               file y1.c:
==========                               ==========
int x, eks = 'x';                        int x, why = 'y';

main()                                   y()
{                                        {
    x = eks;                                 x = why;
    printf("File X1, x: %c\n", x);           printf("File Y1, x: %c\n", x);
    y();                                 }
    printf("File X1, x: %c\n", x);                
}                                

So far, so good.  Now change x to something other than an integer,
recompile, and try to link together x2.obj and y2.obj:

file x2.c:                               file y2.c:
==========                               ==========
int *x, eks = 'x';                       int *x, why = 'y';

main()                                   y()
{                                        {
    x = &eks;                                x = &why;
    printf("File X2, *x: %c\n", *x);         printf("File Y2, *x: %c\n", *x);
    y();                                 }
    printf("File X2, *x: %c\n", *x);
}

Surprise, it's no longer an error!  The linker is happy now, and produces
x.exe.  And of course running x.exe gives the (un)expected side effect:
    File X2, *x: x
    File Y2, *x: y
    File X2, *x: y
Now, just for fun, try linking x2.obj with y1.obj.  Now we have x
defined as (int *) in x2, and x defined as (int) in y1.  The linker is
still happy, and the side effect is even better:
    File X2, *x: x
    File Y1, x: y
    File X2, *x: [ some smiley faces, musical notes, & other ascii "noise" ]

Finally, I took this code over to a Sun3/OS3.5, and it didn't complain
about any of the versions!  Of course, you normally wouldn't code like
this (these examples were simplified from a bug we found in a larger
program).  But what is unique to the MS linker about multiple definitions
of int, but not other types?


Bob Barkan                          rhb6%bunny@harvard.harvard.edu
GTE Labs                            rhb6@gte.com
40 Sylvan Road
Waltham, MA  02254

-- 
Bob Barkan				GTE Laboratories
					40 Sylvan Rd
rhb6%bunny@harvard.harvard.edu		Waltham, MA 02254
rhb6%gte.com@relay.cs.net		(617) 466-2568

rkl1@hound.UUCP (K.LAUX) (10/21/88)

	This reminds me of the old joke:

	Patient:  Doctor!  It hurts when I do this!

	Doctor:  So, don't do that!

greggy@infmx.UUCP (greg yachuk) (10/21/88)

In article <6215@bunny.UUCP> rhb6@bunny.UUCP (Robert H. Barkan) writes:
>
>In MSC 5.x, compile the following 2 files, then link x1.obj and y1.obj.
>The linker should complain because "int x" is multiply defined:
	[ code deleted ]

I just got my 5.1 updgrade yesterday, so I tried your example.
Version 3.65 (which comes with 5.1) doesn't complain about any
of the combinations that you mention.  I tried the 3.61 linker
(from 5.0), and still didn't get any complaints.  Of course, for
the final combo (int x and int *x), the executable was incorrect
from both linkers.

The point is: howcum you linker complained and mine was silent?

>Bob Barkan				GTE Laboratories

Greg Yachuk		Informix Software Inc., Menlo Park, CA	(415) 322-4100
{uunet,pyramid}!infmx!greggy		why yes, I DID choose that login myself

oosten@dutinfd.UUCP (Gertjan van Oosten) (10/21/88)

In article <6215@bunny.UUCP>, rhb6@bunny.UUCP (Robert H. Barkan) writes:
> 
> In MSC 5.x, compile the following 2 files, then link x1.obj and y1.obj.
> The linker should complain because "int x" is multiply defined:

Then follows a description of some source, etc. leading to the exposure
of a linker bug. 

I have another one for you: 

In one C file, I had the following (external) declaration: 
static int x; 

In another C file, I had: 
extern int x; 

Compilation and linkage produced no "Unresolved external" message!!!!! 
How nice of Microsoft.... 

I also tried this on four other machines. Here come the results, fasten 
seatbelts and refrain from smoking: 
A 3B1 running System V version 3.5: 
      No linker error message; however, lint complains about "Used but not 
      defined". 
A Microdutch running System V Release 2 X/OPEN: 
      No linker error message; however, lint complains about "Used but not 
      defined". 
A VAX running 4.3 BSD: 
      Linker produces error message; lint complains. 
A PDP-11/73 running ULTRIX-11: 
      !!!Linker produces error message; lint DOESN'T complain!!! 

So only 4.3 BSD functions correctly; that's ONE out of FIVE!!! 
Enough said... 

		  G. J. van Oosten

"When you come to me
 I'll question myself again
 Is this grip of life still my own?" - David Sylvian 

rhb6@bunny.UUCP (Robert H. Barkan) (10/22/88)

In article <553@infmx.UUCP>, greggy@infmx.UUCP (greg yachuk) writes:
> In article <6215@bunny.UUCP> rhb6@bunny.UUCP (Robert H. Barkan) writes:
> >
> >In MSC 5.x, compile the following 2 files, then link x1.obj and y1.obj.
> >The linker should complain because "int x" is multiply defined:
> 
> Version 3.65 (which comes with 5.1) doesn't complain about any
> of the combinations that you mention.  I tried the 3.61 linker
> (from 5.0), and still didn't get any complaints.  Of course, for
> ...
> The point is: howcum you linker complained and mine was silent?

Apparently, my linkers (V3.61, 3.65) no longer complain [now that everyone
is watching :-( ].  In simplifying the example from about 7000 lines down
to 10, somewhere along the way I deleted whatever made the linker find the
original multiple definition.  I've been unable to find or recreate it,
since the original code has also been changed.  I thought that I had seen
a "symbol already defined" or "symbol multiply defined" message somewhere
with the larger code and also my shorter examples, but it's gone now.
Without any pudding for proof, I retract my original observation.  My
fault for not trying everything one last time before posting!!!

Yes, the second and third examples still produce side effects and/or
garbage on output, but that's just the "Joy of C", not a bug.

Apologies to the net, especially if you went to the trouble of typing
in my examples.
							-Bob
-- 
Bob Barkan				rhb6%bunny@harvard.harvard.edu
GTE Labs				rhb6@gte.com
40 Sylvan Rd				617-466-2568
Waltham, MA 02254

deanr@lakesys.UUCP (Dean Roth) (10/28/88)

If you are using MS's C 5.x or MASM 5.x you *must* use the
linker that comes with the package.  NOTE: this probably means
you must delete the LINK.EXE that is in the DOS directory on your
machine(s) and replace it with the new LINK.EXE.  The LINK.EXE
that is on the DOS diskettes is not compatible with the new
compilers and assembler.  (So why is it still distributed with DOS?
Inquiring minds want to know...)


===================opinions by: Dean A. Roth=======================
{rutgers, uwvax} uwmcsd1!lakesys!deanr           deanr@lakesys.UUCP
P.O. Box 11095                                 Milwaukee, WI  53211  
===================representing Dean A. Roth=======================

allbery@ncoast.UUCP (Brandon S. Allbery) (10/30/88)

As quoted from <1099@dutinfd.UUCP> by oosten@dutinfd.UUCP (Gertjan van Oosten):
+---------------
| In article <6215@bunny.UUCP>, rhb6@bunny.UUCP (Robert H. Barkan) writes:
| > In MSC 5.x, compile the following 2 files, then link x1.obj and y1.obj.
| > The linker should complain because "int x" is multiply defined:
| 
| In one C file, I had the following (external) declaration: 
| static int x; 
| 
| In another C file, I had: 
| extern int x; 
| 
| Compilation and linkage produced no "Unresolved external" message!!!!! 
| How nice of Microsoft.... 
| 
| I also tried this on four other machines. Here come the results, fasten 
| seatbelts and refrain from smoking: 
| A 3B1 running System V version 3.5: 
|       No linker error message; however, lint complains about "Used but not 
|       defined". 
| A Microdutch running System V Release 2 X/OPEN: 
|       No linker error message; however, lint complains about "Used but not 
|       defined". 
| A VAX running 4.3 BSD: 
|       Linker produces error message; lint complains. 
| A PDP-11/73 running ULTRIX-11: 
|       !!!Linker produces error message; lint DOESN'T complain!!! 
| 
| So only 4.3 BSD functions correctly; that's ONE out of FIVE!!! 
| Enough said... 
+---------------

But did you try to run it and see which "x" was in use?

In K&R C, the default storage class of a variable declared outside a function
is "extern".  The corollary is that the "extern" declaration serves both as
reference and as linker definition, i.e. the "extern int x" is a different
variable from the "static int x".  If they have the same address, however,
the linker is broken.  Note also that K&R C isn't followed all that closely
by many compilers in this respect; they instead have the default storage
class as a sort of "invisible" storage class which acts as reference and
definition, while "extern" is merely reference.

++Brandon
-- 
Brandon S. Allbery, comp.sources.misc moderator and one admin of ncoast PA UN*X
uunet!hal.cwru.edu!ncoast!allbery  <PREFERRED!>	    ncoast!allbery@hal.cwru.edu
allbery@skybridge.sdi.cwru.edu	      <ALSO>		   allbery@uunet.uu.net
comp.sources.misc is moving off ncoast -- please do NOT send submissions direct
      Send comp.sources.misc submissions to comp-sources-misc@<backbone>.