Will according to the ISE/IEC 9899:2018 C Standard section 6.3.1.8 you
are incorrect. Please the the emboldened line below.
6.3.1.8 Usual arithmetic conversions
1. Many operators that expect operands of arithmetic type cause
conversions and yield result types in
a similar way. The purpose is to determine a common real type for the
operands and result. For the
specified operands, each operand is converted, without change of type
domain, to a type whose
corresponding real type is the common real type. Unless explicitly
stated otherwise, the common
real type is also the corresponding real type of the result, whose type
domain is the type domain of
the operands if they are the same, and complex otherwise. This pattern
is called the usual arithmetic
conversions:
First, if the corresponding real type of either operand is long double,
the other operand
is converted, without change of type domain, to a type whose
corresponding real type is
long double.
Otherwise, if the corresponding real type of either operand is double,
the other operand is
converted, without change of type domain, to a type whose corresponding
real type is double.
Otherwise, if the corresponding real type of either operand is float,
the other operand is
converted, without change of type domain, to a type whose corresponding
real type is float.64)
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.
Otherwise, if the operand that has unsigned integer type has rank
greater or equal to
the rank of the type of the other operand, then the operand with
signed integer type is
converted to the type of the operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can
represent all of the
values of the type of the operand with unsigned integer type, then
the operand with
unsigned integer type is converted to the type of the operand with
signed integer type.
Otherwise, both operands are converted to the unsigned integer type
corresponding to
the type of the operand with signed integer type.
2. The values of floating operands and of the results of floating
expressions may be represented in
greater range and precision than that required by the type; the types
are not changed thereby. The
cast and assignment operators are still required to remove extra range
and precision. See
5.2.4.2.2 regarding evaluation formats.
On 8/15/2024 6:54 PM, Will Cooke via cctalk wrote:
On 08/15/2024 6:10 PM EDT Mike Katz via
cctalk<cctalk(a)classiccmp.org> wrote:
I'm pretty certain you are wrong about the byte case below. The C standard
says something about no math will be done smaller than a short. I don't have it handy
so can't quote exactly.
But what that means is before the two bytes are added, they are promoted to short /
uint16_t and then added.
int foo( void )
{
uint32_t Long1 = 10;
uint32_t Long2 = 20;
uint16_t Short1 = 10;
unit16_t Short2 = 20;
uint8_t Byte1 = 10;
uint8_t Byte2 = 20;
//
...
// Everything to the right of the equals will not
be promoted at
all, the math will be performed and the result will be promoted to a
uint16 when assigned.
//
Short1 = Byte1 + Byte2;
In this program segment:
uint8_t a = 255;
uint8_t b = 255;
uint16_t c = 0;
c = a + b;
printf("c: %d \n", c);
it will print 510 instead of the 254 that would result if it were added as bytes.
Will
Grownups never understand anything by themselves and it is tiresome for children to be
always and forever explaining things to them,
Antoine de Saint-Exupery in The Little Prince