signed/unsigned integer conversion for right shift seems
Chris Hall
gcc@gmch.uk
Tue Feb 6 21:18:00 GMT 2018
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
More information about the Gcc-help
mailing list