On 06/02/18 18:23, Peter T. Breuer wrote:
Where specifically? I am now looking at the draft standard for
ISO-whatever at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
I am working through the 194 instances of the word "arithmetic"
and the closest I have seen to a statement on the subject is in footnote
48 under paragraph 6.3.13 (I think .. can't see all the page) which
says:
The integer PROMOTIONS are applied only: as part of the usual
arithmetic CONVERSIONS, to certain argument expressions, to the
operands of the unary +, -, and ~ operators, and to both operands of
the shift operators, as specified by their respective subclauses.
which says (wrongly IMO) that promotions are some part of conversions,
but we know what they mean.
At any rate the implication is that CONVERSIONS, comprising as per their
language a carrier for PROMOTIONS, ARE applied to BOTH operands of THE
SHIFT OPERATORS, which seems to me to imply that both operands must be
cast to the same type, otherwise to what type are they to be converted?
Perhaps it has an exception in the "their respective subclauses"
get-out. Where is that ...
Well, it's particularly wet outside and I have nothing better to do, so...
...with apologies for wandering off-topic...
...my copy of ISO/IEC 9899:1999 (relatively inexpensive, and a good read
IMHO) says:
6.3 Conversions
Several operators convert operand values from one type to another
automatically. ... The list in 6.3.1.8 summarizes the conversions
performed by most ordinary operators; it is supplemented as
required by the discussion of each operator in 6.5.
....
6.3.1.8 Usual arithmetic conversions
Many operators that expect operands of arithmetic type cause
conversions and yield result types in a similar way. ... This
pattern is called the usual arithmetic conversions:
So, we have "the usual arithmetic conversions" and those apply to
"several operators" or "many operators" or "most ordinary operators",
but not to *all* operators.
Now, later in 6.3.1.8, having dealt with various forms of 'real' operands:
Otherwise, the integer promotions are performed on both operands.
Then the following rules are applied to the promoted operands:
....
So, "the usual arithmetic conversions" starts with "the integer
promotions" applied to both operands, followed by a step which may then
*convert* one or both to a common type. [In passing, I note that
6.3.1.8 says that "The purpose is to determine a common real type", but
also covers determining a common 'integer' type.]
I suggest to you that (a) the "integer promotions" are a step in the
"usual arithmetic conversions", but they are not the same, and (b) the
"usual arithmetic conversions" are not the *universal* arithmetic
conversions.
Going back to "6.3.1.1 Boolean, characters, and integers", I note:
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(48).
All other types are unchanged by the integer promotions.
3 The integer promotions preserve value including sign. ...
So, here is the definition of the "integer promotions". And the
footnote (48), which you found does indeed say:
48) The integer promotions are applied only: as part of the
usual arithmetic conversions, to certain argument expressions,
to the operands of the unary +, -, and ~ operators, and to
both operands of the shift operators, as specified by their
respective subclauses.
I think you are reading this as:
The integer promotions are applied, as part of the usual
arithmetic conversions, only: to ...
I suggest that it is generally read as:
The integer promotions are applied only:
* as part of the usual arithmetic conversions,
* to certain argument expressions,
* to the operands of the unary +, -, and ~ operators,
* and to both operands of the shift operators,
as specified by their respective subclauses.
and I suggest to you that the ':' *before* "as part of the usual
arithmetic conversions" is key, here.
Accepting that "promotions" does not imply "conversions", and as has
been pointed out elsewhere, the definition of operators in section 6.5
includes:
6.5.5 Multiplicative operators
....
Semantics
3 The usual arithmetic conversions are performed on the operands.
....
6.5.6 Additive operators
....
Semantics
4 If both operands have arithmetic type, the usual arithmetic
conversions are performed on them.
....
6.5.7 Bitwise shift operators
....
3 Semantics
The integer promotions are performed on each of the operands.
The type of the result is that of the promoted left operand.
If the value of the right operand is negative or is greater
than or equal to the width of the promoted left operand, the
behavior is undefined.
Noting that:
* for '<<' and '>>' it's "promotion" *not* "conversion"
cf: '*'. '/', '%', '+' (dyadic) and '-' (dyadic) (inter alia)
where it is explicitly "conversion"
* you could argue that:
"integer promotions are performed on each of the
operands *separately*"
would be *crystal*.
But there is nothing in the definition of the "integer
promotions" that says that the promotion of one operand
has any effect on the promotion of another.
And it does specify that the:
"type of the result is that of the promoted left
operand"
suggesting that the left and right operands may have
different types after the "promotions". (Remembering
that the "usual arithmetic conversions" make the type
of the two operands and the type of the result the
same.)
* and since (see above):
"The integer promotions preserve value including sign."
we cannot expect either argument's sign to change !
Of course, the independence of the promotions means that:
uint64_t s = 12 ;
int v = 91 ;
v << s ; // shifted as 'int'
char t = 12 ;
short w = 91 ;
w << t ; // shifted as 'int'
HTH
Chris