Arithmetic Operation Documentation

We were discussing the finer points of some arithmetic operations in C++ and Rust today. We somewhat quickly found where C++ defines the behavior of << for example, but I could not actually find where Rust describes its behavior.

Am I just bad at navigating the reference? I expected it to be defined here: Operator expressions - The Rust Reference or perhaps linked in each impl Shl<T> for U.

1 Like

In that table in the reference there are notes that give you some information but it is very sparse (I agree that it is lacking).

This footnote tells you what >> does, if you look up the wikipedia definitions of arithmetic and logical shifts:

*** Arithmetic right shift on signed integer types, logical right shift on unsigned integer types.

It is implied that left shifts follow the same rule, but this should be stated.

1 Like

If I were so inclined to try and resolve this, where would I start? I'm unfamiliar with how changes to the reference are proposed and implemented.

The standard library documentation does have a little bit more - if you search for operators it finds the implementing trait, for example:

But it doesn't actually define what the operator does.

The Working Draft C++ Standard 2023-05-10 section 7.6.7 states:

"The operands shall be of integral or upscoped 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 then or equal to the width of the promoted left operand.

The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo 2^N where N is the width of the type of the result.

(Note 1: E1 is left-shifted E2 bit positions; vacated bits are zero-filled.)

The value of E1 >> E2 is E1/2^E2, rounded down.

(Note 2: E1 is right-shifted E2 bit positions, Right-shift on signed integral types is an arithmetic right shift, which performs sign-extension.)


It may be worth noting that this description of C++ is not consistent with the information in Arithmetic operators - cppreference.com under the heading "Built-in bitwise shift operators". I'm unsure when things changed, but the current standard fits my understanding of what most compilers do.

What exactly is inconsistent? Give an example.

From the cppreference website: "For negative a, the behavior of a << b is undefined". The C++ standard I quoted is clearly defined for all signed values of a.

Could be a result of this: p0907r0: Signed Integers are Two’s Complement

But the C++ Standard's language I quoted is a working draft, so I'm not necessarily saying that the cppreference is wrong.

I quoted that text because I believe it most closely matches what Rust does, since Rust has only used 2's complement numbers from the start.

That's in the "(until C++20)" section. Since C++20 it's defined.

1 Like

Ah yes indeed, I missed that over to the right. Sorry for the oversight.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.