FIX: /G3 Optimization Generates Bad Code for Struct Pointers

Last reviewed: September 18, 1997
Article ID: Q116137
1.00 WINDOWS kbprg kbfixlist kbbuglist

The information in this article applies to:

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

SYMPTOMS

The /G3 option, used to generate 386 instructions, may generate incorrect instructions when attempting to access fields within a structure.

RESOLUTION

There are two workarounds to this problem:

  • Compile using the /G2 option.

    - or -

  • Disable optimization locally using the optimize pragma:

             #pragma optimize("",off)
    
             void mycode(void)
             {
             }
    
             #pragma optimize("",on)
    
    

STATUS

Microsoft has confirmed this to be a problem with the C/C++ compiler, version 8.0. The problem was corrected with C/C++, version 8.0c, supplied with Microsoft Visual C++ for Windows, version 1.5. We are researching this problem and will post new information in the Microsoft Knowledge Base as soon as it becomes available.

MORE INFORMATION

The sample code below can be used to illustrate this problem. If you use the /Fc option to generate mixed-source and assembly code, the line commented below generates the following code:

   ;|***    t2 = (lpDisp->right - lpDisp->left);
   ; Line 22
     *** 000027  c4 5e 0c         les bx,DWORD PTR [bp+12]          ;lpDisp
     *** 00002a  66 26 8b 47 0c   mov eax,DWORD PTR es:[bx+12]
     *** 00002f  66 26 2b 47 04   sub eax,DWORD PTR es:[bx+4]
     *** 000034  89 46 f8         mov WORD PTR [bp-8],ax        ;t2
     *** 000037  89 56 fa         mov WORD PTR [bp-6],dx

NOTE: The first three lines of assembly code correctly perform the arithmetic operations, but the last two lines do not use the extended registers "EAX" and "EDX", but "AX" and "DX". Compiling using the /G2 switch instead of the /G3 switch generates correct register use.

Sample Code

/* Compile options needed: /c /G3
*/

   #include <windows.h>

   struct displayinfo
   {
    long leftlim, left, rightlim, right;
   };

   void HorizScrollProc(HWND hWnd, WORD wParam, long lParam,
                        struct displayinfo far *lpDisp)
   {
    long t1,t2;

    switch (wParam)
    {
     case SB_LINEUP:
       t1 = (lpDisp->left + lpDisp->right) / 2;
       t2 = (lpDisp->right - lpDisp->left);        /* bad code here */
       if (lpDisp->leftlim + t2 / 8 > lpDisp->left)
       {
        lpDisp->left = lpDisp->leftlim;
        lpDisp->right = lpDisp->leftlim + t2;
       }
       else
       {
        lpDisp->left -= t2 / 8;
        lpDisp->right -= t2 / 8;
       }
       break ;

     default:
       return;
       break;
    }
   }


Additional reference words: 1.00 8.00
KBCategory: kbprg kbfixlist kbbuglist
KBSubcategory: CLIss
Keywords : CLIss kbbuglist kbfixlist kbprg
Version : 1.00
Platform : 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.