BUG: Wrong Structure Member Modified with /Ox or /Oeg

Last reviewed: August 8, 1997
Article ID: Q136799
The information in this article applies to:
  • The Microsoft C/C++ Compiler (CL.EXE) included with: - Microsoft Visual C++ for Windows, versions 1.5, 1.51, 1.52

SYMPTOMS

When the /Ox or /Oeg optimizations are used with the code listed in this article, the wrong structure member is modified when a huge pointer is incremented.

RESOLUTION

Remove the /Ox or /Oeg optimizations from the command line or use the optimize pragma to disable them from the function that is generating the incorrect code as in this example:

   #pragma optimize("eg",off)
     IncrementFunction(){...}
   #pragma optimize("eg",on)

Another option is to modify the code slightly or change its location. For example, in the following sample if the code from the IncrementFunction() is moved to the calling function, it works correctly.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

Sample Code to Reproduce Problem

   /* Compile options needed: /AL and /Ox or /Oeg
   */
   #include <malloc.h>
   #include <stdio.h>

   typedef struct {
     long x;
     long y;
   } StructA, huge * pStructA;

   typedef struct {
     short points;
     pStructA pPoints;
   } StructB, huge * pStructB;

   #define   NumStructs   2 /* number of StructB structures */
   #define   NumPoints   5 /* number of points per StructB */

   void IncrementFunction( pStructB pStructBs, short numpoints) {
     short i=0;
     for (i = 0; i < NumStructs; i++) {
       if (pStructBs[i].pPoints > pStructBs->pPoints)
          // The points member is incorrectly modified on the next line.
       pStructBs[i].pPoints += numpoints;
     }
   }

   void main(void) {
     pStructB   StructBs = halloc(NumStructs, sizeof(StructB));
     pStructA   datapoints = halloc((NumStructs+1)*NumPoints,
                                     sizeof(StructA));
     short     i=0;
     for (i = 0; i < (NumStructs+1)*NumPoints; i++) {
       datapoints[i].x = datapoints[i].y = (long)i;
     }
     for (i = 0; i < NumStructs; i++) {
       StructBs[i].points = 10;
       StructBs[i].pPoints = &datapoints[i*NumPoints];
     }
     IncrementFunction(StructBs, NumPoints);
     for (i = 0; i < NumStructs; i++) {
       if (StructBs[i].points != 10)
         printf("Error: Value should be 10 and it is %d\n",
                 StructBs[i].points );
     }
   }


Additional query words: 8.00c
Keywords : CodeGen kb16bitonly
Version : 1.5 1.51 1.52
Issue type : kbbug


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