Conversation

I don’t know Rust, so I was wondering how this would look in C++, does anyone have an example?
Quote Tweet
Conceptually, the thing that makes Rust different from modern C++ (and other languages) is the "alias xor mutable" guideline, enforced by the borrow check. You could write C++ that way, but in practice nobody does. It's much stricter than just using smart pointers.
Show this thread
12
15
Replying to
In Rust, you can only hold either one mutable reference or a bunch of immutable references to x. For example: int x = 42; x += 1; // ok const int& r1 = x; // ok x += 1; // Error const int& r2 = x; // ok int& r3 = x; // Error
1
6
Replying to and
or int x = 42; int& r1 = x; // ok r1 += 1; // ok const int& r2 = x; // error int& r3 = x; // error This restriction roots out the possibility of race conditions. And as far as I know, no other major languages (not just C++) have enforcement in this way.
1
3
Replying to and
Mutable references can invalidate other references by freeing allocations, changing the variant in a tagged union, etc. The issue isn't only data races. So, for example, a mutable reference to a std::vector can push to it resulting in use-after-free via other references, etc.
2
3
Replying to and
As an example, if you're looping over a collection in C++, if you accidentally modify the collection, you probably end up with a use-after-free. C++ code does far more allocations/copies than Rust rather than using lightweight references largely because it's hard to do it right.
1
2
If you heavily use std::string_view in C++ as you would use &str in Rust, it would be great for performance but it's begging for having use-after-frees everywhere. C++ copy constructors being the default helps to encourage allocating/copying. It's just the default approach.
1
2
Rust has to enforce mutable references not overlapping with other usable references because there are a bunch of ways that leads to memory corruption. Data races are only one of the ways that can happen. Use-after-free is incredibly common in C and C++, including complex ones.
1
2
Or modifying them in a way that invalidates the other references (push_back on std::vector, etc.), etc. Rust heavily uses tagged unions and assigning another variant type invalidates references to the existing one which would now be pointing at data for a different type.
3