# Increment operator in Rust

**URL:** <https://users.rust-lang.org/t/increment-operator-in-rust/86684>\
**Category:** help\
**Created:** [December 29, 2022, 5:06pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684 "2022-12-29T17:06:10Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![ZiCog](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/zicog/32/12216_2.png) [@ZiCog](https://users.rust-lang.org/u/ZiCog)\
**Post date:** [December 29, 2022, 8:35pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/22 "2022-12-29T20:35:38Z")

</div>

I think this is part of a common misconception by C programmers (and other similar languages) that the language is some how a model of the processor it runs on. Especially among those who started out with C a long time ago. This has not been true for a couple of decades or more now. C employs some notion of an abstract machine it runs on. Which matches actual machines to a greater or lesser extent.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://users.rust-lang.org/u/jbe)\
**Post date:** [December 29, 2022, 9:39pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/23 "2022-12-29T21:39:17Z")

</div>

Handling `+= 1` as a special case (if really necessary at all) is easy for a compiler. A language does not _need_ a special increment operator unless reducing complexity of the _compiler itself_ to a minimum is a goal. Looking at Rust, I see a very complex machinery, where such an optimization (if not done anyway by later stages of generating assembler code) would not be a huge issue.

On the contrary, adding yet another syntax makes the language more complex for humans. Not everyone will start with the programming language C or C++, thus they may not _know_ the `++` syntax. Introducing yet another operator to them can make the language more complex. It does save a character in the source, but not sure if that's really worth it.

Both the advantages and disadvantages are marginal, I would say.

---

<div class="post-metadata">

**Author:** ![Joe232](https://avatars.discourse-cdn.com/v4/letter/j/df705f/32.png) [@Joe232](https://users.rust-lang.org/u/Joe232)\
**Post date:** [December 29, 2022, 11:43pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/24 "2022-12-29T23:43:00Z")

</div>

I agree the removal of `x++;` is to increase safety and avoid confusion, though I wonder why can't you just increment it on its own and disallow people from assigning a variable while incrementing, for example:

```rust
let y = x++:

```

just disallow this but allow this:

```rust
x++;
let y = x;

```

That would make more sense!

---

<div class="post-metadata">

**Author:** ![tczajka](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/tczajka/32/24743_2.png) [@tczajka](https://users.rust-lang.org/u/tczajka)\
**Post date:** [December 29, 2022, 11:57pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/25 "2022-12-29T23:57:19Z")

</div>

Because `x += 1;` already exists, is just as short, clearer, and a lot more general.

---

<div class="post-metadata">

**Author:** ![Joe232](https://avatars.discourse-cdn.com/v4/letter/j/df705f/32.png) [@Joe232](https://users.rust-lang.org/u/Joe232)\
**Post date:** [December 30, 2022, 12:11am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/26 "2022-12-30T00:11:44Z")

</div>

Yes it already does exist but what is wrong with having `x++;` if it is not being assigned to a variable, its kinda like a shortcut and it wouldn't have any confusions as we are disallowing `let y = x++;`?

---

<div class="post-metadata">

**Author:** ![ZiCog](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/zicog/32/12216_2.png) [@ZiCog](https://users.rust-lang.org/u/ZiCog)\
**Post date:** [December 30, 2022, 12:30am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/27 "2022-12-30T00:30:18Z")

</div>

When would you use it?

In C we typically use ++ to increment pointers and to count how many times a `for` loop goes around. Such things are discouraged in Rust so there is no pressing need for a short cut.

To my mind adding 1 to a variable is a significant feature of an algorithm. Why diminish its stature and hide it away with a tiny syntax?

---

<div class="post-metadata">

**Author:** ![tczajka](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/tczajka/32/24743_2.png) [@tczajka](https://users.rust-lang.org/u/tczajka)\
**Post date:** [December 30, 2022, 12:42am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/28 "2022-12-30T00:42:43Z")

</div>

It's not much a shortcut: it would save you from writing only one character, "1". That's the tiniest possible code savings.

Seeing a "1" is a good thing to indicate that a value is incremented by 1. If you now want to change the code to increment by 2, you can easily change it to 2 using the same notation.

"++" is a more cryptic notation than "+= 1".

It would introduce another way of doing the same thing, reducing consistency of code.

It would require adding another two traits to `std::ops`.

User types that implement some sort of arithmetic would have two more traits to implement.

---

<div class="post-metadata">

**Author:** ![Hyeonu](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/hyeonu/32/7970_2.png) [@Hyeonu](https://users.rust-lang.org/u/Hyeonu)\
**Post date:** [December 30, 2022, 2:26am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/29 "2022-12-30T02:26:18Z")

</div>

> [@Miiao](#):
>
> it’s very important to control what’s going on under the hood

If you care what's going on under the hood you should prefer `add 1` over `inc`.

> <https://stackoverflow.com/questions/36510095/inc-instruction-vs-add-1-does-it-matter/36510865#36510865>

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/scottmcm/32/4286_2.png) [@scottmcm](https://users.rust-lang.org/u/scottmcm)\
**Post date:** [December 30, 2022, 10:24pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/30 "2022-12-30T22:24:58Z")

</div>

> [@Joe232](#):
>
> but what is wrong with having `x++;`

That's the wrong question for a language change. All language additions "start with -100 points", because more is bad, all else being equal. The very minimum bar for a language addition is "is this useful enough to overcome the cost of people needing to learn it?".

Thus, for something that's already possible, another way to do it needs to have a combination of being substantially shorter/simpler _and_ that thing being a common enough task to be worth doing. Thus all the feedback in this thread about "the existing way isn't materially longer" and "it's not that common that one needs to do this anyway".

For fun: if you do `let x = 4..;`, then `x++` is `x.next().unwrap()`.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/cad97/32/5076_2.png) [@CAD97](https://users.rust-lang.org/u/CAD97)\
**Post date:** [December 31, 2022, 4:16am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/31 "2022-12-31T04:16:01Z")

</div>

To this point, `++x` has a reason to exist in C++: it's C++'s version of `Iterator::next`.

Well, it's more complicated than that, of course. Because it's C++ I'm talking about. At an overly simplified level, an _iterator_ is any object `r` such that `++r` advances the iterator and `*r` evaluates to the current iterated value. This is the absolute minimum of the pointer API which is technically usable.

`++` is a meaningful operation for C++ to have because increment is a useful operation to have access to in a generic template environment (i.e. for iterators) where adding an integer may not make sense (or could even be given a different semantic by misguided developers).

For Rust, we have semantic, nominal `trait`s rather than purely working from symbols with conventional meaning. The direct analog for most usage is `Iterator::next`, more commonly used via `for $pat in $expr $block` syntax. We don't have the `for (init; test; incr)` form that C and C++ use, so the primary way `++x` gets used just doesn't exist.

That doesn't mean we don't have a separate notion of increment, though; we do, via [`trait core::iter::Step`](https://doc.rust-lang.org/nightly/core/iter/trait.Step.html). However, interestingly enough, the current form of it (as of 1.68.0 (2022-12-30), and originally authored by me\[1\]) doesn't have actual `increment`/`decrement` operations (although it did previously); it just has strided `Step::forward(start, count)` and `Step::backward(start, count)` which take a step `usize`. It also doesn't even take the "iterator" by `&mut`, but operates instead entirely by value/copy. This is because in its current formulation `Step` is purely about expressing the interface used by `Range` to iterate `iNN`/`uNN`/`char` in a way that LLVM can easily cut through the `Iterator` noise, and this happened to be what we found worked.

I don't see us re-adding direct `increment`/`decrement` operations to `Step`; there's already necessarily three "modes" exposed (checked overflow, arbitrary safe overflow, and caller-`unsafe`-guaranteed-no overflow), and inlining constants is perhaps the easiest thing any competent optimizing backend does, so there's minimal if any benefit to emitted code quality along with measurable code maintenance quality pessimations to introducing non-strided forms. `Iterator` covers the iteration case perfectly well, so `Step` doesn't need to.

* * *

1. Like with much of Open Source, for selfish reasons: I really wanted `Range<char>` to be iterable, so I went and [redid the `Step`](https://github.com/rust-lang/rust/pull/69659) trait so the necessary implementation was valid; at that point in time `Step` was in need of some attention anyway, with `replace_one` and `replace_zero` methods going completely unused and semantically not really part of `Step`. Once the new trait version was merged, it was [just a matter of providing the impl](https://github.com/rust-lang/rust/pull/72413).

---

<div class="post-metadata">

**Author:** ![mbratch](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mbratch/32/30329_2.png) [@mbratch](https://users.rust-lang.org/u/mbratch)\
**Post date:** [January 4, 2023, 8:43pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/32 "2023-01-04T20:43:00Z")

</div>

One of the goals of Rust is to prevent the programmer from writing compilable code that results in undefined behavior. The post/pre-increment operator introduces opportunities to create such code. If you're not sure that's true, check all the questions in stack overflow in the C are about why various expressions involving the operator produce unexpected results. 🙂

---

<div class="post-metadata">

**Author:** ![ZiCog](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/zicog/32/12216_2.png) [@ZiCog](https://users.rust-lang.org/u/ZiCog)\
**Post date:** [January 4, 2023, 8:46pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/33 "2023-01-04T20:46:12Z")

</div>

Thing is, if Rust had a ++ operator then some clever clogs would go and create a new "improved" Rust++ language. Better not go down that road.

---

<div class="post-metadata">

**Author:** ![bpjatfb](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/bpjatfb/32/30432_2.png) [@bpjatfb](https://users.rust-lang.org/u/bpjatfb)\
**Post date:** [January 4, 2023, 8:52pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/34 "2023-01-04T20:52:36Z")

</div>

Rust isn't good because it looks like assembly.

Rust is good because it doesn't look like assembly (but still efficient).

---

<div class="post-metadata">

**Author:** ![burjui](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/burjui/32/7562_2.png) [@burjui](https://users.rust-lang.org/u/burjui)\
**Post date:** [January 5, 2023, 6:00am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/35 "2023-01-05T06:00:27Z")

</div>

As a direct counter-example to the original post, RISC-V doesn't have dedicated increment and decrement instructions (can be encoded as `addi dst, dst, 1` and `addi dst, dst, -1`, respectively). Does that mean that C and C++ now have to remove the increment and decrement operators, because both compile to RISC-V? No, there are better reasons to do that 😜

Also, `++` and `--` do not necessarily increment a value by 1: pointers get incremented by `sizeof(pointee)`:

```plaintext
#include <stdio.h>

int main()
{
        int x = 0;
        int *p = &x;
        printf("p: %p\n", (void*) p);
        printf("++p: %p\n", (void*) ++p);
}

```

prints

```plaintext
p: 0x7fff65f0855c
++p: 0x7fff65f08560

```

Fun fact: RISC-V doesn't have "move" and "nop" instructions either, which are encoded, again, with `addi`:

- `mv dst, src` → `addi dst, src, 0`
- `nop` → `addi x0, x0, 0`

What all of that means is that mimicking hardware in language design is pointless. There are many different architectures, each with their own quirks. The reason we have programming languages in the first place is to abstract away from the hardware.

---

<div class="post-metadata">

**Author:** ![user16251](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/user16251/32/30527_2.png) [@user16251](https://users.rust-lang.org/u/user16251)\
**Post date:** [January 5, 2023, 11:06am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/36 "2023-01-05T11:06:31Z")

</div>

It's important to note some history. My understanding is that the increment operator in C was meant to support an addressing mode on the PDP-11 that did operations like `*x++ = y` in a single instruction. The increment or decrement operators themselves are not that useful but in combination with dereferencing they enable very succinct code. However they lend themselves to code that is confusing at best and paradoxical at worst (what does `*++x = *x` do?). Personally I don't mind not having them. I've never seen a style guide for C or C++ that recommended using the dereference and increment idiom.

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [January 5, 2023, 11:29am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/37 "2023-01-05T11:29:34Z")

</div>

While I generally agree with the conclusion of your answer, I'd like to note that in C parlance, incrementing a pointer by 1 unit is incrementing it by 1 unit. We don't say that the pointer incremented by 4 or 8 or however many _bytes_ `sizeof(T)` is; the generally accepted terminology is that pointer arithmetic is implicitly understood in terms of T units, and specific integer values extracted for debugging purposes are irrelevant when discussing the operational semantics of the C abstract machine.

---

<div class="post-metadata">

**Author:** ![tczajka](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/tczajka/32/24743_2.png) [@tczajka](https://users.rust-lang.org/u/tczajka)\
**Post date:** [January 6, 2023, 9:03pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/38 "2023-01-06T21:03:14Z")

</div>

> [@user16251](#):
>
> It's important to note some history. My understanding is that the increment operator in C was meant to support an addressing mode on the PDP-11 that did operations like `*x++ = y` in a single instruction.

[This is false](http://www.bell-labs.com/usr/dmr/www/chist.html).

> People often guess that they were created to use the auto-increment and auto-decrement address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is historically impossible, since there was no PDP-11 when B was developed. The PDP-7, however, did have a few `auto-increment' memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own. Indeed, the auto-increment cells were not used directly in implementation of the operators, and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1.

This shows a few things:

- 1960s compilers didn't optimize. The rationale of the last statement only makes sense in that light.
- Language choices based on special hardware features become outdated quickly because hardware changes faster than programming language features.

Regarding the last point, I think Rust has made a few similar mistakes (`1u32 << 32` doesn't work, and `-3 % 10` returns -3 rather than 7, both are usability failures motivated by contemporary hardware details).

---

<div class="post-metadata">

**Author:** ![m51](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/m51/32/25834_2.png) [@m51](https://users.rust-lang.org/u/m51)\
**Post date:** [January 6, 2023, 10:00pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/39 "2023-01-06T22:00:19Z")

</div>

> [@bpjatfb](#):
>
> Rust isn't good because it looks like assembly.

I had to read this line twice and in context. At first I thought it was the strangest criticism of Rust I'd ever seen.

---

<div class="post-metadata">

**Author:** ![user16251](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/user16251/32/30527_2.png) [@user16251](https://users.rust-lang.org/u/user16251)\
**Post date:** [January 6, 2023, 11:40pm UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/40 "2023-01-06T23:40:43Z")

</div>

Thanks for the correction!

---

<div class="post-metadata">

**Author:** ![khimru](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/khimru/32/31344_2.png) [@khimru](https://users.rust-lang.org/u/khimru)\
**Post date:** [January 7, 2023, 12:23am UTC](https://users.rust-lang.org/t/increment-operator-in-rust/86684/41 "2023-01-07T00:23:39Z")

</div>

> [@tczajka](#):
>
> Regarding the last point, I think Rust has made a few similar mistakes (`1u32 << 32` doesn't work, and `-3 % 10` returns -3 rather than 7, both are usability failures motivated by contemporary hardware details).

Rust did that mistake with conflating `usize` as both `intptr_t` and `size_t`, but I think it did the right call with `<<` and `%`.

> [@tczajka](#):
>
> Language choices based on special hardware features become outdated quickly because hardware changes faster than programming language features.

C developers were certainly burned by that, then C/C++ committees took that idea seriously… and C/C++ developers were burned **again**.

Take that idea about the fact that signed overflow is UB (needed to support one's complement machines, which not even Unisys makes today) or type based memory access rules (extremely important if your coprocessor is separate piece of hardware like Weitek 4167 or just good old 8087)… the fact that these were not optional extensions/relaxations, but mandatory parts of C++ caused untold grief.

Just **what** CPU you have in mind that would work differently?

ARM used to be an example of weird architecture where 1u32 \<\< 32 worked. Today… AArch64… [here we go](https://documentation-service.arm.com/static/62ff43b0e95b0a633aff8a64):

```rust
 result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize, datasize); 

```

RISC-V? Sure: _SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register `rs1` by the shift amount held in the lower 5 bits of register `rs2`_ (for rv32i) and _SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register rs1 by the shift amount held in register rs2. In RV64I, only the low 6 bits of rs2 are considered for the shift amount_ (rv64).

Hardware **used** to be changing faster than programming language features. Not anymore.

Today only highly-specialized hardware can afford to do that (like GPUs) — but they can afford that **precisely** when large pile of existing software written in existing programming languages is not supposed to be used… that, of course, makes it highly unlikely that Rust would be used there a lot, too.

[Previous page](https://users.rust-lang.org/t/increment-operator-in-rust/86684.md?page=1)

[Next page](https://users.rust-lang.org/t/increment-operator-in-rust/86684.md?page=3)
