2

gcc 4.8.4 warns about 1u << 63ul​ (assuming 64 bit long and 32 bit int) and computes 0. Rightfully so (no promotion from 1u​ to 1ul before shifting)?

ISO/IEC 9899:201x, 6.3.1.8 (Usual arithmetic conversions): "Many operators that expect operands of arithmetic type cause conversions"; 6.5.7 (Bitwise shift operators): "The integer promotions are performed on each of the operands...".

But I am not unable to conclude. Which are those "many operators"? As I understand, "integer promotion" does not pertain to types wider than int (am I correct?), but the standard does not explicitly state that the right operand of a bitwise-shift is not taken into account for the implicit type conversion.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Loic
  • 640
  • 4
  • 13
  • 1
    @Olaf: Just because something is obvious to you does not mean it is appropriate to ridicule someone for asking the question. – Dietrich Epp Mar 14 '17 at 13:41
  • @DietrichEpp: Well, it indeed is not clear from the text cited in the question. But the citation from 6.5.7 indeed does provide the answer, as I (hopefully) made clear in my answer. – too honest for this site Mar 14 '17 at 14:08
  • Info about the integer promotions and the usual arithmetic conversions here: http://stackoverflow.com/questions/17312545/type-conversion-unsigned-to-signed-int-char/17312930#17312930 – Lundin Mar 14 '17 at 14:57

2 Answers2

6

Each operation documents this separately. For example, n1548 §6.5.5 "Multiplicative operators" ¶3

The usual arithmetic conversions are performed on the operands.

This phrase is omitted from §6.5.7 "Bitwise shift operators". Instead it says:

The integer promotions are performed on each of the operands. The type of the result is the type of the promoted left operand. …

Since the section on bitwise shift operators says nothing about "usual arithmetic conversions", that conversion does not happen.

Lundin
  • 195,001
  • 40
  • 254
  • 396
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • n1548 is not standard, not even the final draft safe as reference. n1570 **does** contain this statment. OP even cites this passage. – too honest for this site Mar 14 '17 at 13:38
  • @Olaf: Feel free to edit the answer with references to the actual standard if you like. – Dietrich Epp Mar 14 '17 at 13:39
  • @DietrichEpp Thanks for the hint that each operation is documented separately (no list of those "many operators"). One has then to know exactly what "integer promotion" means (in particular that types wider than `int` are left unchanged). I made the mistake to focus on what it does, forgetting what it explicitly does not do. – Loic Mar 14 '17 at 14:28
  • I took the liberty to clarify the answer. It could be read as if the phrase "The integer promotions..." was omitted, which it isn't. – Lundin Mar 14 '17 at 15:01
4

The "usual arithmetic conversions" include conversions to floating point types and how to determine a common type for two operands.

Bitshifts do not operate on floating point types, only integers (constraint, 6.5.7p2). Different than for other binary operators taking integers only (e.g. bit-and), the two operands are not directly combined for the result; there is no requirement to have a common type for the operation. Thus, each operand is independently promoted (from your citation: "The integer promotions are performed on each of the operands").

Reading the whole paragraph 6.5.7p3 makes it clear:

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.

Note the emphasised sentence, which clarifies the result type is solely determined from the left operand. From that and the last sentence follows that int or unsigned int for the right operand is more than sufficient for all current implementations. The lowest upper limit of int (INT_MAX) is 32767 - much more than the number of bits in any standard type of any implementation, even if we consider future wider integers with 1024 and more bits.

Also note that your code invokes undefined behaviour, unless your platform has an unsigned int with at least 64 bits (last sentence).

The compiler correctly warns about your code invoking undefined behaviour. The warning is not required, but you should be glad it does. Treat it seriously! Any behaviour of the program is correct if you invoke undefined behaviour.

If you want a 64 bit type, use uint64_t. For a constant, use the macro UINt64_C(1) which generates an integer constant with at least 64 bits (uint_least64_t). Both are provided by stdint.h.


About your other question:

From 6.3.1.1p2:

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

Community
  • 1
  • 1
too honest for this site
  • 12,050
  • 4
  • 30
  • 52