C9204004: Global Optimization May Generate Incorrect Code

ID Number: Q83227

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

buglist6.00 buglist6.00a buglist6.00ax fixlist7.00

Summary:

PROBLEM ID: C9204004

SYMPTOMS

The Microsoft C Compiler versions 6.0, 6.0a, and 6.0ax may generate

incorrect code when optimizing for global optimizations (/Og).

Under MS-DOS, the example below will not print out 0000:0000, and

it may result in run-time errors because of the incorrect code

generated. Under OS/2, a protection violation occurs when the if

statement inside of the function func() is evaluated.

CAUSE

The problem occurs only when you use global optimizations under

huge memory model (/AH) and your code makes multiple pointer

accesses.

RESOLUTION

Use one of the following workarounds to eliminate the problem in C

versions 6.0, 6.0a, and 6.0ax:

1. Compile without the /Og (global optimization) option.

-or-

2. Use the optimize pragma to change optimizations for the function in

which the error occurs. The example below demonstrates this method.

-or-

3. Compile with the /qc (quick compile) option.

STATUS

Microsoft has confirmed this to be a problem in C versions 6.0,

6.0a, and 6.0ax. This problem was corrected in C/C++ version 7.0.

More Information:

The sample code below demonstrates the problem.

Sample Code

-----------

/* Compile options needed: cl /AH /Og

*/

#include <stdlib.h>

#include <stdio.h>

struct HEAD {

struct HEAD *def;

struct LIST *tag;

} first, second;

struct LIST {

int data;

struct LIST *next;

} tag_1, tag_2;

/* >> REMOVE // ON BOTH #PRAGMA LINES TO MAKE THE CODE WORK */

//#pragma optimize("g",off)

void func ( struct HEAD *hdr )

{

if ( hdr->tag->data != hdr->def->tag->data ) {

hdr->tag = hdr->tag->next;

printf ("if true\n");

}

return;

}

//#pragma optimize("g",on)

void main()

{

first.def = &second;

first.tag = &tag_1;

first.tag->data = 99;

first.tag->next = NULL;

first.def->tag = &tag_2;

first.def->tag->data = 98;

first.def->tag->next = NULL;

func (&first);

printf ("%p\n", first.tag);

}

Additional reference words: 6.00 6.00a 6.00ax