ID Number: Q83219
6.00 6.00a 6.00ax | 6.00 6.00a
MS-DOS | OS/2
buglist6.00
Summary:
PROBLEM ID: C9204002
SYMPTOMS
The Microsoft C Compiler versions 6.0, 6.0a, and 6.0ax may generate
incorrect code when optimizing with /Oweg or /Oaeg.
CAUSE
The C compiler tries to optimize the code by saving a repeated
value for future reference, but incorrectly calculates the value.
The value is incorrectly calculated because of the register
allocation method being used with these compiler options.
RESOLUTION
Use one of the following workarounds to eliminate the problem in C
versions 6.0, 6.0a, and 6.0ax:
1. Compile with the /Os (size optimization) option
-or-
2. Do not compile with the /Og, /Oe, /Oa, or /Ow option.
-or-
3. Use the optimize pragma to change the optimizations for the function
in which the error occurs. The "#pragma optimize" directive is
documented on page 7 of "Microsoft C Advanced Programming
Techniques."
-or-
4. Compile with the /qc (quick compile) option.
-or-
4. Change the code in some way. In the example below, if you declare
var2 as volatile, the program works correctly. Using volatile
causes the compiler to recalculate the 10*var2 for the return
statement. However, the compiler still generates the first instance
of 10*var2 incorrectly. The volatile type-qualifier tells the
compiler that the variable may change at any time. A description of
the volatile keyword can be found on page 14 of "Microsoft C
Advanced Programming Techniques."
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: /Oweg or /Oaeg
Program prints 16 instead of 20.
*/
#include <stdio.h>
int var1 = 29;
char var2 = 2;
char func1 (char arg3)
{
if ((arg3-'0') > (char)(var1 - 10*var2)) /* Optimize bug 10*var2 */
{
if (0 < var1)
return -1;
else
return 0;
}
else
return (char)((arg3-'0') + 10*var2); /* Reuses wrong result */
}
void main()
{
printf("%d",func1('0'));
}
Additional reference words: 6.00 6.00a 6.00ax