News for hackers. Stuff that matters.
Re:Towards fearless SIMD, 7 years later by grandempire on Sunday March 30, 2025 @10:19AM (#43524418)
Exactly. The classic example is invalid pointer deref. It’s too costly to check every deref against every allocation (outside of special debug modes). So the system usually can only detect if there is a virtual memory page fault, in which case it can crash.

In embedded systems without virtual memory there is no validity checking at all. Or it could periodically check (random sampling).

So the standard makes the reasonable choice to leave it undefined. If you can detect it and crash, that’s great. If not and you accidentally overwrite your programs instructions, anything can happen.

Rust only avoids UB in so far as it relies on default clang behavior on modern hardware.

Re:Towards fearless SIMD, 7 years later by jenadine on Sunday March 30, 2025 @11:15AM (#43524827)
> Rust only avoids UB in so far as it relies on default clang behavior on modern hardware.

That's not true.

Rust behaviour avoids UB by not compiling with invalid reference deref because it checks life time.

Clang's behaviour is likely a crash but anything can still happen. It is literally undefined.

Re:Towards fearless SIMD, 7 years later by grandempire on Sunday March 30, 2025 @11:34AM (#43524968)
> Clang's behaviour is likely a crash but anything can still happen.

You act as if clang itself is random. Clang will do and handful of things none of them which will melt your computer.

A given implementation may choose to do anything. Clang and gcc on major operating systems do reasonable things.

> It is literally undefined.

Ok but I’m explaining why undefined is the right thing.

Re:Towards fearless SIMD, 7 years later by jenadine on Sunday March 30, 2025 @12:26PM (#43525345)
The code generated by clang can do anything.

Ok, clang will not directly melt my computer because clang just generates code, but imagine this:

     if (temperature_too_high) 
          lower_temperature();
     
if somewhere else the code access invalid pointer, clang may decide to remove this condition altogether because it thinks it must be dead code, for example. And running this code will melt the computer even though the programmer thought this wouldn't be possible.
Re:Towards fearless SIMD, 7 years later by grandempire on Sunday March 30, 2025 @07:37PM (#43528939)
That’s not true.

A conforming implementation may chose to melt your computer - and you can choose to not use that implementation. But clang and gcc will never melt your Linux.

Once again, a real life example where that is relevant is an embedded device with no memory protection. If you overwrite a buffer you can overwrite the OS code - breaking your computer and requiring you to flash the memory.

It seems there is a lot of misguided accusations going around about who misunderstands UB.

Re:Towards fearless SIMD, 7 years later by eru on Sunday March 30, 2025 @11:47PM (#43530734)
> But clang and gcc will never melt your Linux.

If you use gcc or clang to compile your kernel, they will happily melt your Linux.

Re:Towards fearless SIMD, 7 years later by grandempire on Monday March 31, 2025 @12:38AM (#43531112)
If you're referring to what might happen when you overwrite a buffer in privileged kernel code, yes - but that is true regardless of clang, gcc, or what the C standard says about UB.
Re:Towards fearless SIMD, 7 years later by steveklabnik on Sunday March 30, 2025 @10:35AM (#43524540)
Re Rust, that’s simply not true. Rust relies on compile time validity checks that have nothing to do with virtual memory.
Re:Towards fearless SIMD, 7 years later by grandempire on Sunday March 30, 2025 @11:33AM (#43524957)
You confused two parts. I am not saying that Rust has the same pointer deref, I’m saying that if you try to specify rust you will find parts that implicitly rely on clang or hardware default. In other words the behavior is unspecified.
Re:Towards fearless SIMD, 7 years later by steveklabnik on Sunday March 30, 2025 @11:36AM (#43524984)
The borrow checker has a formal proof and it is completely independent from hardware.
Re:Towards fearless SIMD, 7 years later by grandempire on Sunday March 30, 2025 @11:46AM (#43525052)
Gatorade gives you electrolytes.
Re:Towards fearless SIMD, 7 years later by eru on Sunday March 30, 2025 @11:43PM (#43530696)
> Exactly. The classic example is invalid pointer deref. It’s too costly to check every deref against every allocation (outside of special debug modes). So the system usually can only detect if there is a virtual memory page fault, in which case it can crash.

You could still define what happens.

Eg you could define that whatever error might happen because of invalid pointer deref can't travel back in time. (UB famously can travel back in time: UB at any time during the execution makes the whole execution UB.)

Re:Towards fearless SIMD, 7 years later by dzaima on Sunday March 30, 2025 @11:54PM (#43530784)
UB doesn't allow arbitrary time travel; any time travel you see should be explainable by happening to run code that undoes what was done previously, and where it's not possible to explain it as such it's a compiler bug (ref: wg14 member: https://news.ycombinator.com/item?id=40836898).

This is now clearly standardized, but even without that it's pretty trivial to see how compilers would generally abide by this - if you call an external function that does arbitrary things, it may exit(), so the call can't be optimized even if it's followed by UB. (printf & co are effectively arbitrary calls for these purposes for multiple reasons). And all other behavior is just writing things to memory, which can be undone by happening to write what was there before. (ok there's also volatile, and a bug in clang (not gcc though): https://github.com/llvm/llvm-project/issues/102237)

Re:Towards fearless SIMD, 7 years later by eru on Tuesday April 01, 2025 @09:14PM (#43552856)
Check the ensuing discussion under the comment you linked to. Some limited time travel is still allowed for UB.
Re:Towards fearless SIMD, 7 years later by dzaima on Tuesday April 01, 2025 @10:26PM (#43553162)
There's still no time travel in any of those posts; some may require an explanation of "the compiler replaced the UB division with a call to 'bar'" or something, but "calling 'bar'" is still a subset of the "anything" that UB can result in. If there's a specific example you think doesn't follow that, I'd appreciate a specific reference.

(and singron's mention of SIGSEGV handling is entirely irrelevant; the C standard only cares about the abstract machine; in general real memory state can temporarily appear in arbitrarily weird states in practice if interrupted by a signal even without UB, e.g. https://godbolt.org/z/91ModhbEY will have all a[0..15] written even if there's a handled trap on the write to b[0] (or otherwise an interrupt between the two SIMD writes) (using restrict for simplicity, but taking an 'int n' argument and using that for the loop bound will result in ~the same thing without restrict, just with less direct assembly); the same applies even to Rust, though of course with Rust you shouldn't be able to have a situation where you trap on a safe write; could still have a random interrupt happen in the middle though)