Question about the usual arithmetic conversion

F

Francis Moreau

Hello,

I'm a bit puzzled by the ISO C99 and its section 6.3.1.8.

In particular when I reach the following part:

,----
| Otherwise, the integer promotions are performed on both
| operands. Then the following rules are applied to the promoted
| operands: ...
`----

Then the sub sections are talking about the poreands and their
type. For example the first sub section tells:

,----
| If both operands have the same type, then no further conversion is
| needed.
`----

This is where I don't understand. At this point, in my understanding,
both operands have always the same type and rank since a) an integer
promotion have been performed on both of them, b) the rank of any
unsigned integer type shall equal the rank of the corresponding signed
integer type.

Could anybody enlight me ?

thanks
 
M

Mark Wooding

Francis Moreau said:
,----
| Otherwise, the integer promotions are performed on both
| operands. Then the following rules are applied to the promoted
| operands: ...
`----

Then the sub sections are talking about the poreands and their
type. For example the first sub section tells:

,----
| If both operands have the same type, then no further conversion is
| needed.
`----

This is where I don't understand. At this point, in my understanding,
both operands have always the same type and rank since a) an integer
promotion have been performed on both of them, b) the rank of any
unsigned integer type shall equal the rank of the corresponding signed
integer type.

Consider the case of adding a `long' and a `short'. The integer
promotions are defined in 6.3.1p2:

[#2] The following may be used in an expression wherever an
int or unsigned int may be used:

-- An object or expression with an integer type whose
integer conversion rank is less than the rank of int
and unsigned int.

-- A bit-field of type _Bool, int, signed int, or unsigned
int.

If an int can represent all values of the original type, the
value is converted to an int; otherwise, it is converted to
an unsigned int. These are called the integer
promotions.40) All other types are unchanged by the integer
promotions.

They apply independently to both operands. So the `short' is promoted
to `int', but the `long' is left as it is.

-- [mdw]
 
I

Ike Naar

Hello,

I'm a bit puzzled by the ISO C99 and its section 6.3.1.8.

In particular when I reach the following part:

,----
| Otherwise, the integer promotions are performed on both
| operands. Then the following rules are applied to the promoted
| operands: ...
`----

Then the sub sections are talking about the poreands and their
type. For example the first sub section tells:

,----
| If both operands have the same type, then no further conversion is
| needed.
`----

This is where I don't understand. At this point, in my understanding,
both operands have always the same type and rank since a) an integer
promotion have been performed on both of them, b) the rank of any
unsigned integer type shall equal the rank of the corresponding signed
integer type.
Could anybody enlight me ?

Assume sizeof(short) < sizeof(int) < sizeof(long).

``short + short'', after the integer promotions becomes ``int + int''.
In this case no further conversion is needed.

``short + int'', after the integer promotions becomes ``int + int''.
In this case no further conversion is needed.

``short + long'', after the integer promotions becomes ``int + long''.
Both operands still have different rank so further conversion is needed
(to ``long + long'').
 
J

James Kuyper

Francis said:
Hello,

I'm a bit puzzled by the ISO C99 and its section 6.3.1.8.

In particular when I reach the following part:

,----
| Otherwise, the integer promotions are performed on both
| operands. Then the following rules are applied to the promoted
| operands: ...
`----

Then the sub sections are talking about the poreands and their
type. For example the first sub section tells:

,----
| If both operands have the same type, then no further conversion is
| needed.
`----

This is where I don't understand. At this point, in my understanding,
both operands have always the same type and rank since a) an integer
promotion have been performed on both of them, b) the rank of any
unsigned integer type shall equal the rank of the corresponding signed
integer type.

Other people have already pointed out that while each operand has been
promoted, they could easily have been promoted to different types.

I'd like to point out there is one other way in which the two operands
could still have different types at this point. The types double, double
_Complex, and double _Imaginary are from three different type domains,
though all three have the same corresponding real type: "double". The
usual arithmetic conversions never change the type domain of either operand.
 
F

Franck Bui-Huu

[...]
Consider the case of adding a `long' and a `short'. The integer
promotions are defined in 6.3.1p2:

Damn I completely forgot the long type !

Thanks for you answer.
 
F

Francis Moreau

(e-mail address removed) (Ike Naar) writes:

[...]
Assume sizeof(short) < sizeof(int) < sizeof(long).

``short + short'', after the integer promotions becomes ``int + int''.
In this case no further conversion is needed.

``short + int'', after the integer promotions becomes ``int + int''.
In this case no further conversion is needed.

``short + long'', after the integer promotions becomes ``int + long''.
Both operands still have different rank so further conversion is needed
(to ``long + long'').

Damn I completely forgot about long type !

Thanks for your answer
 
F

Francis Moreau

[...]
Consider the case of adding a `long' and a `short'. The integer
promotions are defined in 6.3.1p2:

Yeah, I forgot about the long type... sorry

Thanks
 
F

Francis Moreau

James Kuyper said:
Other people have already pointed out that while each operand has been
promoted, they could easily have been promoted to different types.

I'd like to point out there is one other way in which the two operands
could still have different types at this point. The types double,
double _Complex, and double _Imaginary are from three different type
domains, though all three have the same corresponding real type:
"double". The usual arithmetic conversions never change the type
domain of either operand.

Hm, I'm probably missing something again but at the point of the part
I mentionned above type can't be double anymore.

Regarding the complex types, it seems that the "usual arithmetic
conversions" purpose is to determine a common real type for the
operands and result.
 
J

James Kuyper

Francis said:
Hm, I'm probably missing something again but at the point of the part
I mentionned above type can't be double anymore.

Sorry - you're right - I didn't think about the implications of the word
"otherwise".
 
T

Tim Rentsch

Francis Moreau said:
Hm, I'm probably missing something again but at the point of the part
I mentionned above type can't be double anymore.

The type of the result can't, but the type of an operand can.

Regarding the complex types, it seems that the "usual arithmetic
conversions" purpose is to determine a common real type for the
operands and result.

A common real type for the operands, but not necessarily the same
type, and a single type for the result, which actually can be
different than the type of either operand. An example is given
with 6.3.1.8p1 footnote 51:

For example, addition of a double _Complex and a float
entails just the conversion of the float operand to double
(and yields a double _Complex result).

If the first operand were of type (double _Imaginary) instead of
(double _Complex), and the second operand were still of type
(float), then the operand types would be (double _Imaginary) and
(double), and yield a (double _Complex) result.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top