Footguns
Footguns
Posted Jul 11, 2021 1:56 UTC (Sun) by khim (subscriber, #9252)In reply to: Footguns by tialaramex
Parent article: Rust for Linux redux
> But in the hypothetical language revision I describe as "equivalent to what Rust has already today" (e.g. a hypothetical C++ 23) this is not Undefined Behaviour, like in Rust you get two's complement arithmetic and so the assert survives the removal of redundant code and fires if you overflow.
This was proposed and rejected. Apparently benchmarks are sacred. Thus it's not happening.
Well… it may happen if people would start abandoning C/C++ ship and switch to Rust (and other languages). But if that would be massive enough movement to make C/C++ committees actually care… then I think it wouldn't matter anymore. So don't expect anything like that any time soon.
> They produce programs with good performance characteristics.They turn working programs into broken ones. Once you pass that threshold “performance characteristics” become secondary concern.
> What can we say about the compiler which turned my incorrect program into a binary which gave one result, versus a different compiler which turned my incorrect program into a binary with a different result? Nothing whatsoever.What can we say about compiler which produces mathematically impossible result? Function which takes an integer and the returns b || !b should always return true. Any mathematician would say so and even just someone who studied logic a bit would say so.
Yet clang would happily turn it into a function which returns false if you give it some variable which is not initialized.
This goes so far beyond the abilities of someone to reason about the program it's not funny.
In theory it's possible to write program which doesn't trigger any undefined behaviors. In practice I haven't see anyone who have done that with programs of size comparable to Linux kernel.
And since undefined behaviors are infectious in modern compilers you have no idea when and how your program would explode. Huge bodies of C code are land mines just waiting to explode is what LLVM developer wrote, not me.
And they are diligently working on a way to detonate them.
> They also use their greater understanding of the language to do something you might value more. They write sanitisers. You can often use LLVM with its sanitizers to find out why your program isn't correct. If you fix all the problems this finds, maybe your program will be correct and you get the results you wanted.Let's go to that infamous realloc example.
Can you show me what kind of sanitizer should I use to catch error in it? Or what compilation option? Or… anything at all, really? Can you even explain why compiler was allowed to provide the output it does?
When I pushed really hard on the issue of “how can two pointers be identical yet one is usable while other is not usable” I have got the answer that yes, standard permits that — when one one is a pointer one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space… and apparently after realloc pointer which was passed to it magically turns into pointer one past the end…
Seriously? This what I should have expected from function which returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated?
Why does it even say that it may have the same value as a pointer to the old object if I couldn't use that fact for anything?
These sanitizers are just catching certain common mistakes. They don't even try to catch many cases of undefined behaviors. Which compiler, nonetheless, would ruthlessly exploit.
> One day GCC learned how to tell whether your printf() format string is bogus at compile time.These were different days and these were different compiler developers. Back then they were not afraid to help developers to write code instead of catering to KPIs. Remember that rant? It may be opinionated but it highlights the story well. 10+ years ago GCC developers cared about real code, and real problems faced by real developers.
But after rise of clang… it all turned into a rat race: gcc and clang looking for a more and more clever ways to punish the developer. Often without even providing any benefits on benchmarks (again: that realloc crazyness definitely doesn't affect any benchmarks). They break the code just because they are allowed to do that.
As simple as that.
> Rust's compiler is allowed to use new features that aren't in the stable language yet because otherwise things get a bit too metaNah. It's because otherwise we would have waited for the stable release of Rust for 10 more years.
It's similar crime to the undefined behavior issue of C: once upon time it wasn't the monstrosity which it turned into recently. But over time something which was supposed to highlight areas of possible conforming language extension turned into monster which threatens to destroy everything.
Only time would tell if Rust would, eventually, stabilize enough internal features to make standard-library stable-Rust compatible or if it would follow in the C footsteps.
I, certainly, hope that lessons were learned. But we wouldn't know any time soon.
