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).