3 ms·
One thing that is still "implementation-defined" in C and C++ is the result of a right shift of a negative integer. On pretty much all platforms, the >> operato
by Findecanor 3y ago
One thing that is still "implementation-defined" in C and C++ is the result of a right shift of a negative integer.
On pretty much all platforms, the >> operator shifts in the sign bit and does not round the result — which makes it equivalent to flooring division by a power of two.
It is consistent with the division operator only when the left-hand value is positive.
- kazinator 3y agoHowever, the oposite shift is undefined if a 1 goes into the sign bit. More precisely, regarding E1 << E2, it is written (in the April 2023 ISO C draft): "If E1 has a signed type and nonnegative value, and E1 × 2ᴱ² is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined." Thus if E1 is negative, or if the result overflows, UB.
- rcfox 3y agoDidn't they specify two's complement signed integers somewhat recently? What's the rationale for leaving these behaviours undefined?
- kazinator 3y agoBecause the shift operations are arithmetically defined, and the situations that are undefined correspond to overflow. v << 1 means the same thing as v * 2 and is undefined if v * 2 is undefined.
- Findecanor 3y agoOn some CPUs architectures, the operand size for some instructions could be larger than an `int`, in which case the upper part of a CPU register would become invalid on overflow instead of containing an extension of the sign bit. There are also CPUs that do "saturating arithmetic" where overflow results in INT_MAX instead of wrapping.