Ugh if you read the article, you would know that the UB described here is the same in Rust. There is this massive group think about which languages are safe and/or fast, and whenever an article like this comes up, invariably someone says "Rust!" without really looking at the problem itself.
Personally, I am in wait and see mode on Rust. Without better generics support (aka template <size_t> or similar) and a number of other things, it still doesn't meet my bar for writing fast generic code, and who knows how complex it will be at that point? I say the jury is still out.
Rust doesn't have a formal memory model yet, but it's already known that UB in Rust is quite restricted:
https://doc.rust-lang.org/nomicon/what-unsafe-does.html
Most importantly, UB in Rust should only arise if you're writing unsafe code (barring compiler bugs). Typically, most Rust code is safe. This is a huge win.
Rust does have vocal proponents, but I don't see how "the UB described here is the same in Rust". Rust should trap consistently when dividing by zero.
I don't think this is correct. Dividing by zero in Rust produces a panic, and panics are observable side effects that may not be reordered with other side effects. This is sometimes annoying, because it can prevent the compiler from eliminating bounds checks in some cases, but it avoids the problems mentioned in this article.
Ugh, if you took the time to learn Rust before criticizing it, you'd know that Rust only allows undefined behavior in unsafe blocks.
> Without better generics support
So you have no idea what generics are. Templates aren't generics, they're fancy code generators expanded at compile time, which means they're incredibly loosely typed and allow you to do things like have scalar parameters like size_t n (because they're basically macros). C++ templates are essentially a form of duck typing that has led to an increased need for specification, hence concepts in C++20.
Rust's parametric polymorphism and type classes (aka generics) follows in the ML and Haskell tradition in that the type checking is like a constraint program that is run at compile time. When a generic item is invoked, the specification of that type is immediately checked for consistency at the call site, otherwise the typechecking fails.
UB isn't "crazyness" it's just a detail to be aware of.
A compiled binary that worked correctly won't suddenly run into undefined behaviour, that can only happen if you upgrade compiler versions or change compilation flags. But this only happens while the application is still actively developed and tested.
The CVE history of the major browser vendors indicate that this is currently an unsolved problem for their large C++ applications.
Upgrading the compiler version and causing undefined behavior sounds pretty sudden. Here's my favorite story along those lines: http://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-...
I don't know. I often help colleagues out with things like preprocessor nonsense and violations of the One Definition Rule.
A lot of it has to do with difficult build and packaging tools. Actually standardizing a module system will be an important step in the right direction.
But please, please also look into its platform support table[1], too. If you're the slightest bit opposed to the Windows/macOS/Linux hegemony, you may want to reconsider Rust.
That's how I'd do it anyway.
People don't have infinite time and only search for security issues in software that's actually in use.
Which is one of the reasons that C/C++ appear more often in CVEs.
I love how people hand have the fact that even projects like the Linux kernel, with their stringent processes aren't able to avoid CVEs, to the point it became the major focus of Linux Kernel Security Summit 2018.
Yet we all know that only newbies do major errors in C. /s
Rust has no undefined behavior because it only supports one CPU and has only one compiler implementation.
When Rust supports a dozen architectures and has three different compiler implementations then Rust will be just as full of UB as C++. Except with the added "bonus" of all the UB being brand-new and unspecified, unlike the well-known portability pitfalls of C++.
"Rust now available on 14 Debian architectures" https://lists.debian.org/debian-devel-announce/2018/11/msg00...
Because they prefer to loose a couple of ms to paying the price of the ultimate performance might bring.
Like in real life you can speed at 300 KMH with a 1200cc motorbike, or doing it a car with reinforced structure wearing seatbelts and airbags.
Even with diminished chances of survival, I rather be in the car.
Also, implementation-specific details aren't always about maximizing performance. Compilers implement languages slightly differently because of architecture and OS differences and because it's easier that way for the people writing compilers.
Other systems languages manage to do it quite well.
It was really a shame that Bell Labs gave UNIX away for a symbolic price during 10 years before being allowed to actually sell it.
We wouldn't be having this kind of C related talks.
That is not true. Rust works on multiple architectures.
Titus Winters just did a great talk at Pacific++ outlining how difficult it is to understand the quirks of C++. Not even Bjarn can keep all of it in his head. The dice are completely loaded against you to fail and introduce bugs, unintended behavior, and vulnerabilities in your code.
Rust isn't a silver bullet that will suddenly fix your life, but it doesn't deal with the crazyness of C undefined behavior and doesn't have to be backwards compatible. It's designed from the ground up to make comprehensive sense, and safety is a feature enforced for you by the compiler in many cases.