Comment by zozbot234

9 months ago

TBF this is not really true. Unsafe Rust is a lot harder than comparable C/C++, because it must manually uphold all safety invariants of Safe Rust whenever it interacts with idiomatic Rust code. (These safety invariants are also why Safe Rust can often be compiled into better-optimized code than the idiomatic C/C++ equivalent.)

With more enforced correctness of Rust (also unsafe Rust) I mean small details like Rust not allowing implicit conversion between integer types. That alone eliminates a pretty big source of hidden bugs both in C and C++ (especially when assigning a wider to a narrower type, or mixing signed and unsigned integers).

All in all I'm not a big fan of Rust, but details like this make a lot of sense (even if they may appear a bit draconic at first) - although IMHO Zig has a slightly better solution by allowing implicit conversions that do not lose information. E.g. assigning a narrower to a wider unsigned integer type works, but not the other way around.

I wonder if Rust is killing flies with canons (as we say in spanish). There are perfectly safe alternatives or very safe ones.

Even in a project coded in Modern C++ with async code included, activating all warnings (it is a cards game) I found two segfaults in like almost 5 years... It can happen, but it is very rare at least with my coding patterns.

The code is in the tens of thousands of lines of code I would say, not sure 100%, will measure it.

Is it that bad to put one share pointer here and there and stick to unique pointers and try to not escape references? This is ehat I do and I use spans and string views carefully (you must with those!). I stick to the rule of zero. With all that it is not that difficult to have mostly safe code in my experience. I just use safe subsets except in a handful of places.

I am not saying C++ is better than Rust. Rust is still safer. What I am saying is that an evolution of the C++ model is much more ergonomic and less viral than this ton of annotations with a steep learning curve where you spend a good deal of your time fighting the borrow checker. So my question is:

- when it stops being worth to fight the borrow checker and just replace it with some alternative, even smart pointers here and there? Bc it seems to have a big viral cost and refactoring cost besides preventing valid patterns.

  • > What I am saying is that an evolution of the C++ model is much more ergonomic and less viral than this ton of annotations with a steep learning curve where you spend a good deal of your time fighting the borrow checker. So my question is:

    That "evolution of the C++ model" (the C++ Core Guidelines) has an even steeper learning curve than Rust itself, and even more invasive annotations if you want to apply it across the board. There is no silver bullet, and Rust definitely has the more principled approach to these issues.

  • I'm not answering your question here, just saying my opinion on C++ vs Rust. I think that the big high-level difference (before diving into details like ownership and the borrow checker) is that C++'s safety is opt-in, while Rust's safety is opt-out. So in C++ you have to be careful each time you allocate or access memory to do it in a safe way. If you're working in a team, you all have to agree on the safe patterns to use and check that your team members are sticking with it during code rewiews. Rust takes this burden from you, at the expense of having to learn how to cooperate with the borrow checker.

    So, going back to your question, I think that the answer is that it depends on many factors, including also some non-strictly-technical ones like the team's size.

    • An evolution of the C++ model could be something like Hylo. Hylo is safe. Hylo does not need a borrow checker. Hylo does not need a garbage collector.

      That is what I mean by evolution. I do not mean necessarily C++ with Core Guidelines.

      1 reply →

Unsafe Rust is not harder or safer than C/C++. If you can uphold all safety invariants for C/C++ code (OMG!), then it will be easier to do same thing for unsafe Rust, because Rust has better ergonomic.

  • Better ergonomics for what? For refactoring with a zillion lifetime annotations? Annotations go viral down the stack call. That is a headache. Not useless. I know it is useful. Just a headache, a price to pay. For linked structures? For capturing an exception.

    No, it is not more ergonomic. It is safer. That's it.

    And some parts of that enforcement via this model is terribly unergonomic.