FIX: Global Code Optimization Generates Incorrect Code

Last reviewed: September 18, 1997
Article ID: Q115527
7.00 | 1.00 1.50 MS-DOS | WINDOWS kbtool kbfixlist kbbuglist

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE), included with:

        - Microsoft C/C++ for MS-DOS, version 7.0
        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    

SYMPTOMS

The code below illustrates a bug in the C/C++ compiler that occurs when the /Ox, /Ol, /Oe, or /Og compiler switch is used. As a result of the optimization, the code below is stuck executing an infinite loop because of source code optimization. By using the /Fc compiler option, the code within the if statement is optimized out of the source code, as shown in the assembly output.

RESOLUTION

There are four workarounds to this problem:

  • Use the fast compiler. You can force the compiler to use this option by adding the /f option.

    -or-

  • Compile without the /Ox, /Ol, /Oe, or /Og options.

    -or-

  • Disable optimization for the function generating the incorrect code. This is done by using the optimize pragma as follows:

          #pragma optimize("",off)
    

          int test_func(void)
          {
           /* .... */
          }
    

          #pragma optimize("",on)
    

    -or-

  • In the case of the code shown below in the "MORE INFORMATION section, repeat the line:

          state=0;
    

    to cause the compiler to generate the correct assembly code.

STATUS

Microsoft has confirmed this to be a bug in the products listed above. This problem was corrected in C/C++ compiler version 9.0, included with Visual C++ 32-bit Edition, version 2.0.

MORE INFORMATION

The following sample demonstrates this problem.

Sample Code

/* Compile options needed: /c /Fc /Ox (or /Ol, /Oe, or /Og)
*/
      #include <stdio.h>

      static int fault, state;

      int test_func (void)
      {
         if (state == 2)
         {
            state=0;         // No code generated for this block if
      optimized
         /* state=0; */      // works if this line's comment is removed
            if (fault == 0)  //
               return(1);      //
            else             //
               return(-1);     //
         }
         else
            return(0);
      }

      void main(void)
      {
         state = 2;

         while (test_func() == 1);
         printf("done\n");
      }


Additional reference words: 1.00 1.50 7.00 8.00 8.00c
KBCategory: kbtool kbfixlist kbbuglist
KBSubcategory: CodeGen
Keywords : CodeGen kb16bitonly kbbuglist kbfixlist kbtool
Version : 7.00 | 1.00 1.50
Platform : MS-DOS WINDOWS
Solution Type : kbfix


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: September 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.