This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: signed/unsigned integer conversion for right shift seems


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]