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

ID: Q136799

The information in this article applies to:

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          : kb16bitonly kbCodeGen 
Version           : 1.5 1.51 1.52
Issue type        : kbbug

Last Reviewed: August 11, 1997