Reputation: 4523
Please see the code below, why no integral promotion for literal "1"?
long long n = 50;
long long a = 1 << n; // 262144
long long b = 1LL << n; // 1125899906842624
Upvotes: 2
Views: 1742
Reputation: 753695
As requested by elazar:
The result shown is an acceptable result because the shift invokes undefined behaviour. That's because the plain 1
is an int
, and shifting an int
by a value outside the range 0..(sizeof(int) * CHAR_BIT)-1
(normally, 0..31
) leads to undefined behaviour.
Note that the type of a shift is affected only by the type of the (promoted) left-hand operand. This is (as chris noted at one time) different from most other binary operators, such as addition, where the types of both operands influence the type of the result. Of course, the type of an assignment is controlled by the type of the left operand and the value on the right is coerced to the correct type if necessary (but the value on the right of an assignment is calculated without reference to the type that it will be assigned to, as in this example).
§6.5.7 Bitwise shift operators
¶3 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.
§5.8 Shift operators
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.
Upvotes: 12
Reputation: 320451
I suspect that you mixed integral promotions and usual arithmetic conversions.
Integral promotions promote smaller integral operands to int
or unsigned int
types. Since 1
is already an int
, it cannot be promoted any further.
Usual arithmetic conversions bring operands of binary operators to common type (like it happens in case of binary +
, for example), which is then used to perform the actual calculation. I suspect that you expected these conversions to occur in your example, since the right-hand operand has long long
type. I.e. you probably expected your 1
to get converted to long long
type as well. However, usual arithmetic conversions are simply not performed for bitwise shift operators. They are performed for additive, multiplicative, relational operators and so on, but not for bitwise operators. This is why 1
remains an int
and the code triggers undefined behavior.
Upvotes: 3
Reputation: 21595
Here is an equivalent code:
long long n = 50;
int x = 1;
x <<= n; // sizeof(x) is 4, probably. 32 bit. we are shifting it by 50.
long long a = x;
long long z = 1LL;
z <<= n;
long long b = z;
Is it more clear now?
Upvotes: 3