the other operators are fine, but multiply
uses a 16bit intermediate:
volatile unsigned char s,t;
void main()
{
s=t*5; // this uses an 16 bit intermediate
s=t/5; // whereas the other operators are fine
without
s=t%5;
s=t+5;
s=t-5;
}
According to the ANSI type conversion rules the code
generated by SDCC is correct for the multiplication example
and the array-access.
The code generated for /%+- is incorrect!
5 is an integer constant (there ain't no such thing as a char
constant!!), so both operands have to be converted to int;
the result of the operation is then cast back to char.
Similar for the array access:
sizeof (something) returns size_t, which - in most cases - is
"typedef int size_t;" or "#define size_t int".
Again we start with one int and one char (the index i) which
has to be promoted to int.
To keep ANSI compatibility, please DON'T change the
behaviour for the multiplication, but correct the behaviour for
operators /%+-.
The user can force use of 8-bit operation by an explicit cast
(well, should be, didn't try!).
Taking into account the memory- and runtime-constraints of
embedded systems, you might implement some #pragma to
force 8bit operations, or something a "char-suffix" (similar to
the long-suffix L).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is acceptable to skip integer promotion as long as the
same result is obtained as if the promotion occurred (often
referred to as the "as-if semantics"). A quote from ISO/IEC
9899-1999 (the C-99 standard), section 5.1.2.3 Example 2:
"In executing the fragment
char c1, c2;
/* ... */
c1 = c1 + c2;
the "integer promotions" require that the abstract machine
promote the value of each variable to int size and then add
the two ints and truncate the sum. Provided the addition of
two chars can be done without overflow, or with overflow
wrapping silently to produce the correct result, the actual
execution need only produce the same result, possibly
omitting the promotions."
The user can't force the use of 8-bit operation by an
explicit cast since the integer promotion rules make no
exception for dealing with the result of a cast. You can
explicitly cast to char all you want, but the rules will
still cause a final cast to int before the operator is
applied. 8-bit operations are only possible using the as-if
semantics.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Eric, as far as I understand the ISO documents, that rule
comes into effect only, when the operands are of the same
type...
ISO/IEC 9899/1999 - 6.3.1.8:
"... (conversion rules for float and double) ...
Otherwise, the integer promotions are performed on both
operands. Then the following rules are applied to the
promoted operands:
-- If both operands have the same type, then no
further conversion is needed.
-- Otherwise, if both operands have signed integer
types or both have unsigned integer types, the
operand with the type of lesser integer conversion
rank is converted to the type of the operand with
greater rank.
..."
(ranks are defined in 6.3.1.1, and rank (int) > rank (char))
According to 5.1.2.3 ex. 2 the promotion can be skipped, but
the type conversions have to be done in any case.
Because 5 is of type int (there is no char constant (6.4.4.1)),
the other operand (t) has to be converted (not promoted!) to
int as well (2nd rule), even though promotion was skipped.
On the other hand, when you cast the int constant to a char
constant ((char) 5), no conversion has to be done (1st rule).
I mixed up "promotion" and "conversion" in my first post, sorry.
And 5 is an int constant, not an integer constant (sorry once
again).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
5 is an 'unsigned char' in SDCC, and it would be very unwise
to choose anything else. If it would be an int, the code size
would explode.
In this special case I don't care about a violation of the
standard. But I take much care about the correctness of the
results. The correct result is of course defined by the
standard.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Logged In: YES
user_id=888171
This also applies to indexing an array of elements with size
<256.
long int x[];
long y;
unsigned char i;
y = x[i];
Both i and sizeof(x[0]) get cast up to int and _mulint is called.
Logged In: YES
user_id=203539
The array access has been fixed at least in SDCCicode.c 1.183
Logged In: YES
user_id=850360
According to the ANSI type conversion rules the code
generated by SDCC is correct for the multiplication example
and the array-access.
The code generated for /%+- is incorrect!
5 is an integer constant (there ain't no such thing as a char
constant!!), so both operands have to be converted to int;
the result of the operation is then cast back to char.
Similar for the array access:
sizeof (something) returns size_t, which - in most cases - is
"typedef int size_t;" or "#define size_t int".
Again we start with one int and one char (the index i) which
has to be promoted to int.
To keep ANSI compatibility, please DON'T change the
behaviour for the multiplication, but correct the behaviour for
operators /%+-.
The user can force use of 8-bit operation by an explicit cast
(well, should be, didn't try!).
Taking into account the memory- and runtime-constraints of
embedded systems, you might implement some #pragma to
force 8bit operations, or something a "char-suffix" (similar to
the long-suffix L).
Logged In: YES
user_id=635249
It is acceptable to skip integer promotion as long as the
same result is obtained as if the promotion occurred (often
referred to as the "as-if semantics"). A quote from ISO/IEC
9899-1999 (the C-99 standard), section 5.1.2.3 Example 2:
"In executing the fragment
char c1, c2;
/* ... */
c1 = c1 + c2;
the "integer promotions" require that the abstract machine
promote the value of each variable to int size and then add
the two ints and truncate the sum. Provided the addition of
two chars can be done without overflow, or with overflow
wrapping silently to produce the correct result, the actual
execution need only produce the same result, possibly
omitting the promotions."
The user can't force the use of 8-bit operation by an
explicit cast since the integer promotion rules make no
exception for dealing with the result of a cast. You can
explicitly cast to char all you want, but the rules will
still cause a final cast to int before the operator is
applied. 8-bit operations are only possible using the as-if
semantics.
Logged In: YES
user_id=850360
Eric, as far as I understand the ISO documents, that rule
comes into effect only, when the operands are of the same
type...
ISO/IEC 9899/1999 - 6.3.1.8:
"... (conversion rules for float and double) ...
Otherwise, the integer promotions are performed on both
operands. Then the following rules are applied to the
promoted operands:
-- If both operands have the same type, then no
further conversion is needed.
-- Otherwise, if both operands have signed integer
types or both have unsigned integer types, the
operand with the type of lesser integer conversion
rank is converted to the type of the operand with
greater rank.
..."
(ranks are defined in 6.3.1.1, and rank (int) > rank (char))
According to 5.1.2.3 ex. 2 the promotion can be skipped, but
the type conversions have to be done in any case.
Because 5 is of type int (there is no char constant (6.4.4.1)),
the other operand (t) has to be converted (not promoted!) to
int as well (2nd rule), even though promotion was skipped.
On the other hand, when you cast the int constant to a char
constant ((char) 5), no conversion has to be done (1st rule).
I mixed up "promotion" and "conversion" in my first post, sorry.
And 5 is an int constant, not an integer constant (sorry once
again).
Logged In: YES
user_id=203539
5 is an 'unsigned char' in SDCC, and it would be very unwise
to choose anything else. If it would be an int, the code size
would explode.
In this special case I don't care about a violation of the
standard. But I take much care about the correctness of the
results. The correct result is of course defined by the
standard.
Logged In: YES
user_id=203539
Fixed, see ChangeLog 1.605
The new type flow is enabled with the environment variable
SDCC_NEWTYPEFLOW
Discussion in sdcc-user