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

Last reviewed: July 18, 1997
Article ID: Q116238
1.00 1.50 WINDOWS kbtool kbbuglist

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE), included with: Microsoft Visual C++ for Windows, versions 1.0 and 1.5

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 : CodeGen kb16bitonly kbbuglist kbtool
Version : 1.00 1.50
Platform : WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.