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