Why can't I increment a variable like this?


#1

x++;

Why is this invalid, other languages allow you to increment a variable by one like this, why can’t you do this in Rust?


#2

Check out the Rust FAQ: Why doesn’t Rust have increment and decrement operators?


#3

Preincrement and postincrement (and the decrement equivalents), while convenient, are also fairly complex. They require knowledge of evaluation order, and often lead to subtle bugs and undefined behavior in C and C++. x = x + 1 or x += 1 is only slightly longer, but unambiguous.

How does it lead to more bugs if I typed ++x instead of x += 1??


#4

People can make mistakes when reading/writing code, around the ++x (pre-increment) or x++ (post increment) operators.

pre-increment:

int array[] = {0, 1, 2};
int i = 0;
printf("%d\n", array[++i]); // prints 1

post-increment:

int array[] = {0, 1, 2};
int i = 0;
printf("%d\n", array[i++]); // prints 0

By removing the possibility for that kind of confusion, the opportunity for the mistake is removed


#5

Isn’t it obvious that ++x would be the same as x += 1?

I don’t know this is just personally me?

Wouldn’t a more suatable approach be that during compiling, the compiler warns the user that it is not recommended not using ++x or x++? Shouldn’t the programmer have the freedom to choose how he does his work?


#6

I think it’s not the x += 1 part that isn’t obvious, but the return value. In pseudo-ish code:

// x++
int original = x;
x = x + 1;
return original;

// ++x
x = x + 1;
return x;

#7
// increments i.
// er, no wait, it's a no-op.
// uhhhh........??????????
i = i++;

// Here's a fun one. If you've done any serious C/C++ programming,
// you've probably written this yourself.
// 
// ...did you know it was undefined behavior prior to C++17?
// Language lawyering is tough.
a[i] = i++;

// This one is STILL undefined behavior.
n = ++i + i;

Examples taken from cppreference.


#8

No; warnings are for behavior that is likely to be incorrect, not (usually) for issues of stylistic preference, and in general you should not simply choose to ignore them. In any language, but especially in Rust, you should try to make your code compile with no warnings.

Adding new syntax, however trivial, makes the language and the compiler more complicated. Adding syntax that is not recommended and simultaneously adding a warning to discourage actually using that syntax would be counterproductive. (And as noted in other comments, this syntax is not as trivial as it may appear!)


#9

In Rust assignments returns (), so you can’t use the value of an increment expression inside another expression. This is a good thing, because assignments in expressions can cause bugs, mostly due to ambiguities in evaluation order.

Also, you should prefer iterators over manually incrementing indexes.

So a special abbreviation syntax is not warranted. On the contrary, it is a good thing that you have to type the slightly longer x += 1.


#10

For what it’s worth, they had this operator in Swift and removed it a couple of years ago because of very similar reasons as the ones stated in this thread.

Reference: https://github.com/apple/swift-evolution/blob/master/proposals/0004-remove-pre-post-inc-decrement.md


#11

Well the simple i++ or ++i might look innocent. But it often gets complex when you use it as part of a bigger expression.


#12

I feel like it could make sense to allow i++ or ++i, but have it return (). So it’s only a short form of an assignment, and cannot be used in error prone ways like in the examples given by the other posters.
It would just be a nice abbreviation, and not cause more errors.


#13

At that point it’s an abbreviation of a single character, but one more bit of syntax that has to be maintained in the compiler forever, and learned by readers of Rust code.


#14

Freedom to shoot yourself in the foot is not a rust marketing point :wink:


TWiR quote of the week
#15

Can’t agree with this strongly enough. Practically every time I’ve seen non-formatting-related warnings from the Rust compiler it has pointed to a genuine bug in my code.


#16

Also, Rust has had iterator-based for loops from the beginning, so it doesn’t need increment operators as much as C does.