Why can't I increment a variable like this?

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?

7 Likes

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

10 Likes

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??

2 Likes

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

16 Likes

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?

2 Likes

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;
3 Likes
// 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.

42 Likes

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!)

18 Likes

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.

16 Likes

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

13 Likes

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

8 Likes

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.

1 Like

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.

19 Likes

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

29 Likes

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.

10 Likes

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

8 Likes

At least when Rust hits schools, tests won't be full of questions like:

What is the result of this statement? "x+++++x"

...like it was in our Java test.

17 Likes

++ and -- were originally put into C to map to the post-increment and pre-decrement addressing modes in the PDP-11. That is because C was originally designed as a thin wrapper over the PDP assembly. These addressing modes are used for a lot of stack-pointer movements (that's why you don't get pre-increment or post-decrement).

C++ originally compiled down to C, so it picked them up from there.

Frankly speaking, although they allow you to write dense code, they tend to become cryptic and hard to read, and you have to constantly keep in mind what value you're using.

There are multiple places where C syntax can probably be made denser but is not, so the argument for shorter/denser code with ++ and -- is dubious. In a modern language, the ambiguities (undefined behavior) and subtle bugs introduced probably make them not worth keeping, as += 1 is not that much longer to type.

It did remove the ability to embed multiple actions within a single statement... Some may feel it makes the language less powerful... other will see that it makes code less confusing.

6 Likes

I for one am very glad that Rust does not have those auto increment operators.

They may have been useful in C if your compiler could not spot an opportunity to use an auto-increment instruction optimization then you had to tell it explicitly.

They have always been redundant in the language itself, apart from saving a few character to type.

Given the better ways we have to make loops and such in Rust auto-increment is even less useful.

They cause programmer confusion.

Just because C did a thing one way once upon a time does not mean that all subsequent languages have to blindly follow. I am very impressed at the way Rust rethinks many things we have taken for gospel for so long.

6 Likes

I wish this wisdom were followed more often with Rust. For example, the nastiness that is the unary-not operator (!). That should die a horrible death. :slight_smile:

3 Likes