Bad Code Generated for Consecutive Long Constants Operations

ID Number: Q73037

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

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

Summary:

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

incorrect code for two consecutive long constant operations. The

following information details two particular situations when this

occurs, and these problems are also demonstrated by the sample code

below.

Scenario 1

----------

Using no optimization (/Od), any memory model, regular compiler or

quick compiler (/qc), if two statements performing calculations with

long math are located on the same line, the compiler may generate

incorrect code. To work around the problem, change the code so the

instructions are on separate lines, as in the good_func_od() example

below.

Scenario 2

----------

With any optimization other than /Od, the problem may occur even if

the two statements are on separate lines. To work around the problem,

change the code so that the instructions are on separate lines and

code (such as a function call) separates the two assignments, as in

the good_func_any() example below.

More Information:

In the sample code, there is an assignment of one long variable to

another followed by an addition of a long constant to a long variable.

The compiler may recognize only the low 16 bits in the second

statement and fail to perform the 32-bit calculation needed to add in

the long constant.

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

and 6.0ax. This problem was corrected in C version 7.0.

Sample Code

-----------

/* Compile options needed: /Od (for Scenario 1)

none (for Scenario 2)

*/

#include <stdio.h>

void bad_func( long x, long y);

void good_func_od( long x, long y);

void good_func_any( long x, long y);

void main( void)

{

printf( "X should be 0 and Y should be 43647642\n");

bad_func( 0L, 0L);

good_func_od( 0L, 0L);

good_func_any( 0L, 0L);

}

void bad_func( long x, long y)

{

x = y; y += 43647642L; // This doesn't work.

printf( "X = %ld, Y = %ld\n", x, y);

}

void good_func_od( long x, long y)

{

x = y; // This works with /Od.

y += 43647642L;

printf( "X = %ld, Y = %ld\n", x, y);

}

void good_func_any( long x, long y)

{

x = y; // This works with other optimization.

printf( "X = %ld, Y = %ld\n", x, y);

y += 43647642L;

printf( "X = %ld, Y = %ld\n", x, y);

}