P1236R1 — C++20 defines the signed shifts
P1236R1 (Jens Maurer, 9 November 2018) is the wording paper for JF Bastien's P0907, Signed Integers are Two's Complement, adopted into C++20. Read via research pass 2026-09-28 as the contrast case for wg14-n2412.
What it does to the shift operators
- Left shift: the value of
E1 << E2becomes "the unique value congruent to E1 × 2^E2 modulo 2^N", where N is the width of the result type. Left-shifting a negative signed value is now defined. - Right shift: the value of
E1 >> E2is "E1 / 2^E2, rounded down", with a note that for signed operands this "is an arithmetic right shift, which performs sign-extension." The implementation-defined case for negativeE1is removed. - Still undefined: a negative shift count, or one at least the width of the promoted left operand.
What it does not do
Signed overflow stays undefined. The paper adds a note to that effect: "Overflow for signed arithmetic yields undefined behavior," while unsigned arithmetic does not overflow.
Why it matters here
The shift used by branchless-abs (x >> 31 as a sign mask) is guaranteed in C++20 and later, and still
implementation-defined in C23 (wg14-n2412). The C committee saw this paper and chose not to follow it
on shifts and overflow.
Tier
T1. The adopted wording paper for the C++ standard change.