ID Number: Q80103
5.10 | 5.10
MS-DOS | OS/2
buglist5.10 fixlist6.00
Summary:
PROBLEM ID: C9201004
SYMPTOMS
When using the Microsoft C Compiler version 5.1, incorrect code may
be generated when passing structures to a function and compiling
with the compact (/AC) or large (/AL) memory model.
RESOLUTION
To work around this problem, do one of the following:
1. Change the code so the problem no longer occurs. For example,
declare the structure variable as a static array rather than an
array of pointers. Then remove the for loop that allocates space
to those pointers.
-or-
2. Use different optimizations. In the sample below, /Oa causes the
compiler to generate the correct code.
STATUS
Microsoft has confirmed this to be a problem in Microsoft C version
5.1. This problem was corrected in Microsoft C version 6.0.
More Information:
The sample code below demonstrates a code generation error for the
following line:
writing(a[i][j]);
The compiler generates a stack pointer subtraction immediately before
a data segment push causing an incorrect value to be popped into the
DS register after the memory moves take place. Below is the assembly
listing of the line that is incorrect:
Assemble Listing
----------------
;|*** writing(a[i][j]);
mov ax,17
imul WORD PTR [bp-4] ;j
mov bx,WORD PTR [bp-2]
shl bx,1
shl bx,1
mov es,$T20001
mov cx,WORD PTR es:_a[bx]
mov si,WORD PTR es:_a[bx+2]
add cx,ax
sub sp,18 ; The order of these two lines should be changed.
push ds
push si
mov si,cx
mov di,sp
push ss
pop es
pop ds
ASSUME DS: DGROUP
mov cx,8
rep
movsw
movsb
pop ds
ASSUME DS: DGROUP
push cs
call _writing
add sp,18
Note that the code above pops a value off of the stack into the DS
register. Because the area of the stack that is popped off is
overwritten by the memory moves, the program hangs on the call to
_writing.
Sample Code
-----------
/* Compile options needed: /AL
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct str
{
char string[17];
}*a[2];
void writing(struct str b)
{
printf("b.string=%s\n",b.string);
}
void main(void)
{
int i,j;
for(i=0;i<2;i++)
{
if((a[i]=malloc(2*sizeof(struct str)))==NULL)
{
printf("Could not allocate.\n");
exit(1);
}
}
strcpy(a[i=0][j=0].string,"test");
printf("a[%d][%d]=",i,j);
writing(a[i][j]);
}
Additional reference words: 5.10 6.00