PRB: C 6.xx May Generate Bad Code for Initialization of Local

ID Number: Q74355

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

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

Summary:

SYMPTOMS

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

incorrect code for an initialization of a local variable. When a

local variable is initialized but is never directly referenced, the

compiler may optimize out the initialization.

RESOLUTION

The following workarounds may be used to eliminate the problem in C

versions 6.0, 6.0a, and 6.0ax:

- Compile with the /Od (disable optimizations) option.

-or-

- Use the optimize pragma to disable optimizations for the

function in which the error occurs. The "#pragma optimize"

directive is documented on page 7 of the "Microsoft C Advanced

Programming Techniques" manual that ships with C versions 6.0,

6.0a, and 6.0ax.

-or-

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

-or-

- Eliminate unnecessary use of the asterisk (*) and ampersand (&)

characters. See the comment in the sample program below.

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 this problem. When the program is

run, the function call should return the hex value 6362 (which is the

hex values for the characters "c" and "b"), but it returns garbage

instead. This problem can occur in all memory models with any

optimizations other than /Od.

Looking at the assembly code generated when optimizing shows that no

code is generated for the initialization of the local variable

local_char. This occurs because local_char is not referenced directly;

the address of local_char is taken with the ampersand, then the

address is dereferenced with the asterisk. Because local_char is never

referenced directly anywhere in the code, the compiler optimizes out

the initialization.

Sample Code

-----------

/* Compile options needed: none

*/

#include <stdio.h>

void main (void);

unsigned int abcd (void);

void main ()

{

if ( 0x6362 == abcd() )

printf ("passed\n");

else

printf ("failure\n");

}

unsigned int abcd()

{

unsigned int val;

unsigned char local_char[4]= "abcd";

val= *((unsigned int *)(&local_char[1]));

/* val = ((unsigned int)(local_char[1])); this will work */

return val;

}

Additional reference words: 5.10 6.00 6.00a 6.00ax