Hi,
I made a small program to make the problem clear:
==================
void problem(void) { unsigned char ii; unsigned char jj; unsigned char flag; for (ii=0;ii<0xff;ii++) { for (jj=0;jj<0xff;jj++) { if (ii * jj < 0xff) { if (ii * (unsigned int)jj < 0xff) flag = 1; // ok else flag = 2; // not ok } } } }
=================== I have a double for loop, both loop counters are of type unsigned char. When I do a compare: if (ii * jj < 0xff), the outcome sometimes is wrong (flag = 2). That can be checked with the same expression using an explicit (unsigned int) cast.
The first three combinations which yield an incorrect result are: ii=0x82, jj=0xfd ii=0x82, jj=0xfe ii=0x83, jj=0xfb
I am using the following compiler: C51 COMPILER V9.51 - SN: K1NGC-DAEVIE COPYRIGHT Copyright (C) 2012 ARM Ltd and ARM Germany GmbH. All rights reserved.
on a C8051F587 processor.
Questions: o Do you agree that this is a bug in the compiler? o Is this a known bug?
But note that as I write the C51 compiler requires a specific compiler flag to follow the C standard rules of extending the data to sizeof(int) before computing the expression result.
Without that flag specified, it's irrelevant what the C standard says, because the C51 expression evaluation is then not following the standard.
The standard puts a minimum size of an int, and requires data to be extended. If you have a rule that the unsigned value 255 is small enough to fit into a signed int, that rule is irrelevant if the compiler - by design - doesn't upgrade to a 16-bit expression.
It's really important to remember that 16-bit expressions are way more expensive to evaluate for a processor that must use multiple 8-bit instructions. With add, it's enough with a couple of loads, a single add and a add-with-carry. But a 16x16 multiply expands to quite a number of 8-bit instructions. The end result? That some expressions will give different results if compiled with or without that C51 flag, because of the differences with/without the numeric overflow or the difference in involved sign bits.