ID Number: Q61974
5.10 | 5.10
MS-DOS | OS/2
buglist5.10 fixlist6.00
Summary:
When an unsigned character variable is used to index the first 256
elements of an array whose size is greater than 256, erroneous results
may occur. This problem occurs when the variable is declared locally
and maximum optimization (Ox) or loop optimization is enabled with
relaxed alias checking (Ola). To work around this problem, either
declare the unsigned character variable outside of main, or do not use
the aforementioned compiler options, or both.
Sample Code
-----------
/* Compile with /Ox or /Ola to illustrate the problem. */
#include <stdio.h>
void main(void)
{
int i, data[512];
unsigned char c; /* For correct results, make this global. */
for (i=0; i<512; i++)
data[i] = i;
for (c=0; c<256; c++) /* Compare c to 256 to illustrate the */
/* problem. */
printf("data[%d] = %d\n", (int)c, data[c]);
}
More Information:
The problem lies mostly in the fact that overflow conditions are
undefined. Because the compiler can do whatever it wants in an
overflow situation, programmers should not write code that relies on a
specific behavior occuring during an overflow situation.
In this particular case, the compiler puts the address of the start of
the array in a 16-bit register (SI). After each iteration of the loop,
the register is incremented by 2 to account for the 2-byte shift for
the next element of the array. If the loop were to actually stop at
255, this behavior would work fine. However, in this case, when the
loop counter resets to 0 (zero), the register is not reset and
continues incrementing until a protection violation (OS/2) occurs or
the program crashes (DOS). This problem is caused by a failure to
execute an "AND SI, 255" instruction after each increment.
Microsoft has confirmed this to be a problem with C version 5.10. This
problem was corrected in C 6.00, which will now perform the required
"AND" instruction.