[comp.sys.ibm.pc] Bug in Microsoft C 4.00?

go@orstcs.UUCP (02/13/87)

[in case of line eater]

I don't know if anyone has reported this as a bug in this group, but here
goes...

In Microsoft C 4.00, (actually more a linker problem, but it's the linker
supplied with the compiler) the linker can, in some cases, allocate
memory to variables, such that the variables overlap.  Consider the
two modules:

/* module a */
int array1[100];

main()
	{
	extern int array2[];

	printf("address of array1 is %x, end of array1 is %x\n",
		array1, array1+sizeof(array1));

	printf("address of array2 is %x\n",
		array2);
	}
/* end of module a*/

/* module b */
int array2[100];
/* end of module b */

Compile both using the small (default) memory model and link with
slibc and run.  You will find that array2 is allocated somewhere
within the limits of array1.  The problem disappears if you
explicitely initialize either array.

I have not yet tried this on any other memory models.  Is this a bug
or am I just too tired to see what's wrong?

Gary Oliver
...!hp-pcd!orstcs!go

[Perhaps we need a comp.sys.ibm.pc.microsoft.bugs  :-) ]

go@orstcs.UUCP (02/15/87)

Boy.  Sometimes I really goof up!

Regarging the "alleged" bug post of mine (for Microsoft C V4.00), please
note that I goofed.
 
Before all you good people fill my mailbox with "...you stupid idiot.."
I should point out (as someone just did to me..) that there is a GROSS
mistake on my part in my bug post.  The test programs given work just
fine when one considers that (red face inserted here) array+sizeof(..)
is not the same as (char *) (array) + sizeof(.) in the case where array is
an int array.  Boy, I feel stupid.

Anyway, the attempt was to show a bug (which I cannot seem to demonstrate
with a simple program) that caused two arrays to share space.  In the
real program, array1 was a character array of text strings and
array2 was an array of pointer-to-structures in another module that
was being initialized to NULL pointers.  When array2 was an
automatically (linker) created array, the initialization left the
text string array full of double-nulls.  When I simply added a
"= {0}" initialization to array2 (of pointers), the problem went away.

No, there were no fancy pointer manipulations here.  Everything
was being done with "array[subscript] = NULL;" inside a "for"
loop.

I'll keep my trap (and keyboard) shut until I find a suitably short
(reliable) demonstration of the bug.

Gary Oliver
...!hplabs!hp-pcd!orstcs!go

konigsfe@uicsrd.UUCP (02/16/87)

>	printf("address of array1 is %x, end of array1 is %x\n",
>		array1, array1+sizeof(array1));

As I see it, there is nothing wrong with the compiler or linker
but just your (or maybe its mine) perception of what the compiler is
doing.  In the above code array1 was an array of integers with 100
elements.  This gives it a size of 200 bytes.  It appears that
array1+sizeof(array1) should give the address of array1 plus 200, but
the compiler will assume that you are giving an offset to an integer
pointer, array1,  and really add 2 for every integer offset.  
In other words the compiler multiplies the pointer offset (sizeof(array1)) 
by the size of element pointed to by array1 (sizeof(int) = 2) and 
therefore adds 400 instead of 200.  

If this explination is wrong, please let me know because much of my
code will need to be reevaluated. 

Disclaimer:  I don't claim to be smart, I've just failed enough times
to make me learn. 

Kris Konigsfeld
UUCP:	 {ihnp4,seismo,pur-ee,convex}!uiucdcs!uicsrd!konigsfe
ARPANET: konigsfe%uicsrd@a.cs.uiuc.edu
CSNET:	 konigsfe%uicsrd@uiuc.csnet
BITNET:	 konigsfe@uicsrd.csrd.uiuc.edu

boykin@custom.UUCP (02/16/87)

In article <216700008@orstcs.UUCP>, go@orstcs.UUCP (go) writes:
> I don't know if anyone has reported this as a bug in this group, but here
> goes...
> In Microsoft C 4.00, (actually more a linker problem, but it's the linker
> supplied with the compiler) the linker can, in some cases, allocate
> memory to variables, such that the variables overlap.
... Extraneous stuff deleted
> int array1[100];
> 	printf("address of array1 is %x, end of array1 is %x\n",
> 		array1, array1+sizeof(array1));
> 
> 	printf("address of array2 is %x\n",
> 		array2);
> You will find that array2 is allocated somewhere
> within the limits of array1.

This is not a bug at all, but a misunderstanding of what happens
with 'sizeof' and pointer arithmetic.  Sizeof returns the number of BYTE's
of its operand.  For an integer array with 100 elements this will
be at least 200 (maybe 400, maybe more!).  When you add this value to 'array1'
(which is the address of the first element of the array,  you are
getting the address of the 200th (400th) element.  Array two then
appears to lie inside of array1, but in fact does not.  Hence, no
bug in MSC, just a little misunderstanding.

The reason the problem "goes away" when you initialize one of the arrays
is that initialized data gets dealth with slightly differently.  Under
UNIX(tm) this would be the data area, vs. the bss area of uninitialized
data.

Joe Boykin
Custom Software Systems
...{necntc, frog}!custom!boykin

gemini@homxb.UUCP (02/17/87)

In article <216700009@orstcs.UUCP>, go@orstcs.UUCP (go) writes:
> Anyway, the attempt was to show a bug (which I cannot seem to demonstrate
> with a simple program) that caused two arrays to share space.

There is a bug in the linker, somewhere.  I can't be sure, but I
had the same problem when I mixed assembler and MS 4.0.  Some of the
assembler declared variables ended up loaded over the top of the
C variables.  Some, but not all.  I gave up, and declared the problem
ones in the C portion and the problem went away.  I haven't got time
to chase down anything but the "workaround" any more.

Rick Richardson, PC Research, Inc. (201) 922-1134, (201) 834-1378 @ AT&T-CP
..!ihnp4!castor!{rer,pcrat!rer} <--Replies to here, not to homxb!gemini, please.

gardner@kodak.UUCP (02/18/87)

In article <2395@homxb.UUCP> gemini@homxb.UUCP (Rick Richardson) writes:
>There is a bug in the linker, somewhere.  I can't be sure, but I
			^---- (Microsoft)
>had the same problem when I mixed assembler and MS 4.0.  Some of the
>assembler declared variables ended up loaded over the top of the
>C variables.  Some, but not all.  I gave up, and declared the problem
>ones in the C portion and the problem went away.  I haven't got time
>to chase down anything but the "workaround" any more.
>
I just went through a painful experience that might be related.  I was
putting together some function libraries that were originally written
for Lattice C, and had huge number of errors on all of the functions
written in assembler.  After a lot of trouble, I found that there are
several rules to be followed when integrating assembler:

	1 - All PUBLIC labels (function names) must be preceeded by
	    an underscore character.
	2 - The code segment must be named '_TEXT' (at least in the
	    small model, which is all I used. See the manual for segment
	    names for larger models.)
	3 - The 'class' must be type 'CODE'.  My experience with this
	    is also limited to the small memory model.

I hope this is helpful.


=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

             Dick Gardner
             Eastman Kodak Co.
             Rochester, New York  14650
             (716) 477-1002
       UUCP: seismo!rochester!kodak!gardner

To err is human -- to really screw it up
		   you need a computer!
=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
  

prove@batcomputer.UUCP (02/19/87)

In article <2395@homxb.UUCP>, gemini@homxb.UUCP (Rick Richardson) writes:
> In article <216700009@orstcs.UUCP>, go@orstcs.UUCP (go) writes:
> > Anyway, the attempt was to show a bug (which I cannot seem to demonstrate
> > with a simple program) that caused two arrays to share space.
> 
> There is a bug in the linker, somewhere.  I can't be sure, but I
> had the same problem when I mixed assembler and MS 4.0.  Some of the
> assembler declared variables ended up loaded over the top of the

This problem sounds familiar to me too, at least the part about wierd
problems in linking asm to MS C (v3 or 4).  Adding irrelevent printf's
would make the difference between a program that functioned normally
and one that crashed on startup.  The problem seemed to be that 
segments in the asm program have to be declared byte aligned.  Since
doing this I have had no problems.  I would have thought that the linker 
would catch any inconsistancy like this.  There also seems to be no
mention of such a requirement in the msc manual (v3).