Bitwise operators and signed types

后端 未结 3 1850
你的背包
你的背包 2021-02-09 07:37

I\'m reading C++ Primer and I\'m slightly confused by a few comments which talk about how Bitwise operators deal with signed types. I\'ll quote:

Quote #1

3条回答
  •  礼貌的吻别
    2021-02-09 07:52

    It might be simplest to read the exact text of the Standard, instead of a summary like in Primer Plus. (The summary has to leave out detail by virtue of being a summary!)

    The relevant portions are:

    [expr.shift]

    1. The shift operators << and >> group left-to-right. The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

    2. The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

    [expr.unary.op]/10

    The operand of ˜ shall have integral or unscoped enumeration type; the result is the one’s complement of its operand. Integral promotions are performed. The type of the result is the type of the promoted operand.

    Note that neither of these performs the usual arithmetic conversions (which is the conversion to a common type that is done by most of the binary operators).

    The integral promotions:

    [conv.prom]/1

    A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

    (There are other entries for the types in the "other than" list, I have omitted them here but you can look it up in a Standard draft).


    The thing to remmeber about the integer promotions is that they are value-preserving , if you have a char of value -30, then after promotion it will be an int of value -30. You don't need to think about things like "sign extension".

    Your initial analysis of ~'q' is correct, and the result has type int (because int can represent all the values of char on normal systems).

    It turns out that any int whose most significant bit is set represents a negative value (there are rules about this in another part of the standard that I haven't quoted here), so ~'q' is a negative int.

    Looking at [expr.shift]/2 we see that this means left-shifting it causes undefined behaviour (it's not covered by any of the earlier cases in that paragraph).

提交回复
热议问题