BUG: Code Generation Problem with /Oc and /f Compiler Options

ID: Q116238

1.00 1.50 WINDOWS kbtool kbbuglist

The information in this article applies to:

SYMPTOMS

A structure assignment produces incorrect results when you use the /Oc compiler option (local common subexpression optimization) in conjunction with the /f option (fast compile). This also happens when the /Ox compiler option is used in conjunction with the /f option, because /Ox includes /Oc as one of its optimizations.

CAUSE

The assembly that is generated when you use the optimization stores the value of the array in the AL register, but then proceeds to use AX for another purpose before actually storing the value in the structure element. The original value of AL is then lost and the structure element is assigned an incorrect value.

RESOLUTION

To work around this problem, either do not use the /Oc or /Ox optimization or disable the optimization for the function that contains the code by using the #pragma optimize("",off) option.

STATUS

Microsoft has confirmed this to be a bug in the C/C++ Compiler for MS-DOS, versions 8.0 and 8.0c. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

This is not a problem in the 32-bit C/C++ Compiler, versions 8.0 and 9.0, which support neither the /Oc option nor the /f option.

MORE INFORMATION

The following sample code demonstrates this problem:

Sample Code

/* Compile options needed: /f /Oc
*/ 

   static struct
   {
      char a[3];
   } s[10];

   static char x[] = "ABCDEFGHIJ";

   int main(void)
   {
      int i;
      memset(&s,0,sizeof(s));
      for (i=0; i<10; i++)
      {
         s[i].a[0] = x[i];  //bad code generated from this line
         printf("s[%d] = ""%s""\n", i, s[i].a);
      }
   }

//The following line of code produces the incorrect assembly:

; Line 13
;                 s[i].a[0] = x[i];
; Line 14
     *** 000025     mov     bx,WORD PTR -4[bp]
     *** 000028     mov     al,BYTE PTR x[bx]  // x[i] is moved into
     *** 00002c     mov     cx,OFFSET 3    // the AL register
     *** 00002f     mov     ax,bx          // the x[i] value in AL is
     *** 000031     imul     cx             // then overwritten
     *** 000033     mov     bx,ax
     *** 000035     mov     BYTE PTR s[bx],al  // the last value in AL
                                        // is moved into the structure
                                        // but the AL value is incorrect

//This is the example rewritten using the #pragma to work around the
//problem:
/* Compile options needed: /f /Oc
/*
   static struct
   {
      char a[3];
   } s[10];

   static char x[] = "ABCDEFGHIJ";

   #pragma optimize("c",off)

   int main(void)
   {
      int i;
      memset(&s,0,sizeof(s));
      for (i=0; i<10; i++)
      {
         s[i].a[0] = x[i];
         printf("s[%d] = ""%s""\n", i, s[i].a);
      }
   }

   #pragma optimize("c",on)

Additional reference words: 1.00 1.50 8.00 8.00c KBCategory: kbtool kbbuglist KBSubcategory: CodeGen
Keywords          : kb16bitonly kbCodeGen kbbuglist
Version           : 1.00 1.50
Platform          : WINDOWS

Last Reviewed: July 22, 1997