Earlier quoted context omitted.
The key is "that must be enforced at non-zero runtime cost." Safe Rust is indeed generally free of UB, but that requires bounds checks at a minimum. > I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB That's kind of what Rust does - overflow is not UB, but you can use unchecked_add/mul/div/sub…
How does Rust as a language avoid the "UB" traps that are fundamentally just compiler optimizations? For example in the case where you have an array of 8 elements, you access the element at index x, then (in program order) test whether x is less than 8. It seems than an optimizing compiler with a known-bits analysis could conclude that x is always less than 8, and remove that test. I don't know much about languages,…
Why do we need for an Undefined Behavior Annex to C++
11–20 of 76 posts
Re: Why do we need for an Undefined Behavior Annex to C++
#12Earlier quoted context omitted.
How does Rust as a language avoid the "UB" traps that are fundamentally just compiler optimizations? For example in the case where you have an array of 8 elements, you access the element at index x, then (in program order) test whether x is less than 8. It seems than an optimizing compiler with a known-bits analysis could conclude that x is always less than 8, and remove that test. I don't know much about languages,…
Rust performs a runtime check to protect against out of bounds array accesses. In some cases those checks can be optimized out if the compiler can prove it's not needed.
Re: Why do we need for an Undefined Behavior Annex to C++
#13Earlier quoted context omitted.
The key is "that must be enforced at non-zero runtime cost." Safe Rust is indeed generally free of UB, but that requires bounds checks at a minimum. > I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB That's kind of what Rust does - overflow is not UB, but you can use unchecked_add/mul/div/sub…
How does Rust as a language avoid the "UB" traps that are fundamentally just compiler optimizations? For example in the case where you have an array of 8 elements, you access the element at index x, then (in program order) test whether x is less than 8. It seems than an optimizing compiler with a known-bits analysis could conclude that x is always less than 8, and remove that test. I don't know much about languages,…
This is in contrast to C, where the out of bounds access us merely undefined, so the compiler is allowed to have the program continue execution passed it.
Re: Why do we need for an Undefined Behavior Annex to C++
#14Earlier quoted context omitted.
I don’t know. Safe rust has 0 UB although if I recall correctly things are still a bit messy with integer overflow. I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB and for all other UB require an explicit annotation acknowledging it or just a warning and a missed optimization instead. The cur…
The key is "that must be enforced at non-zero runtime cost." Safe Rust is indeed generally free of UB, but that requires bounds checks at a minimum. > I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB That's kind of what Rust does - overflow is not UB, but you can use unchecked_add/mul/div/sub…
It's also got a great ecosystem. I love the assume crate to do these annotations instead of writing unsafe code explicitly:
assume!(unsafe: i
Now you've explicitly written an assumption that will cause the compiler to elide the bounds check in release mode but still assert it in debug mode (vs just doing unsafe & using variants that bypass the bounds check).Re: Why do we need for an Undefined Behavior Annex to C++
#15Earlier quoted context omitted.
Rust performs a runtime check to protect against out of bounds array accesses. In some cases those checks can be optimized out if the compiler can prove it's not needed.
This is my point precisely. Having proven to itself that 0 <= x < 8, the compiler could go on to remove any test for x < 8, right?
Re: Why do we need for an Undefined Behavior Annex to C++
#16Great stuff. It looks like a ton of upfront work, but will greatly improve the standard, and shouldn't be too hard to maintain once it's complete.
Once it's complete, make it authoritative. Any mention of undefined behavior should be required to reference the corresponding item in the UB annex.
Re: Why do we need for an Undefined Behavior Annex to C++
#17Earlier quoted context omitted.
No, because UB is not avoidable in principle unless you create a walled garden/sandbox that must be enforced at non-zero runtime cost.
I don’t know. Safe rust has 0 UB although if I recall correctly things are still a bit messy with integer overflow. I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB and for all other UB require an explicit annotation acknowledging it or just a warning and a missed optimization instead. The cur…
Safe Rust aims for 0 UB, but I don't think you can make the claim that it absolutely has no UB.
This program SEGFAULTs on my system (macOS), because it's reading an invalid memory address due to a stack overflow:
const N: usize = 1024*1024*1024;
fn main() {
let var: [u8; N] = [0; N];
println!("var: {:?}", var);
}Re: Why do we need for an Undefined Behavior Annex to C++
#18Earlier quoted context omitted.
I don’t know. Safe rust has 0 UB although if I recall correctly things are still a bit messy with integer overflow. I could imagine a world where we define annotations around “signed integer will never overflow” that you can add to hit paths but otherwise disallow optimizing around that UB and for all other UB require an explicit annotation acknowledging it or just a warning and a missed optimization instead. The cur…
> Safe rust has 0 UB Safe Rust aims for 0 UB, but I don't think you can make the claim that it absolutely has no UB. This program SEGFAULTs on my system (macOS), because it's reading an invalid memory address due to a stack overflow: const N: usize = 1024*1024*1024; fn main() { let var: [u8; N] = [0; N]; println!("var: {:?}", var); }
Rust's semantics are to abort on a stack overflow. A language like C or C++ have no such semantics, they may abort or they may continue running and producing jibberish.
Re: Why do we need for an Undefined Behavior Annex to C++
#19This is great.
Re: Why do we need for an Undefined Behavior Annex to C++
#20Earlier quoted context omitted.
Rust performs a runtime check to protect against out of bounds array accesses. In some cases those checks can be optimized out if the compiler can prove it's not needed.
This is my point precisely. Having proven to itself that 0 <= x < 8, the compiler could go on to remove any test for x < 8, right?