The way the C standard ends up working is they can just take the shortcut of making everything undefined, even changing things to be *retroactively* undefined, and then other languages without that option using the same compilers are just completely screwed.
Conversation
So for example, type-based alias analysis is important for other languages, but in those other languages it actually has to be a sound model / implementation or it can't be used. Similarly, the pointer provenance stuff is important to them, but it actually has to be sound too.
1
So, I find the whole thing frustrating, based on my perspective where these rules are internal to the compiler, and don't actually make the language less safe to use, unless they are broken. Sadly, they are okay with stuff simply being broken or partially fleshed out for perf.
2
It's so stupid that they expect non-C / non-C++ languages to mark every maybe non-terminating loop or potentially recursive call as having a side effect. It would completely destroy optimization just to work around them not making a sound model and falsely justifying it via C.
2
Non-termination *is a side effect*. A function which does not terminate is not pure in any reasonable sense of the word.
1
No language needs to cater to optimization of functions which don't obviously terminate. Writing such functions is a bug - either a behavioral bug (if it turns out really not to terminate) or an analyzability bug (correctness is non-obvious).
1
Turning non-termination into memory corruption and other awfulness isn't something that safe languages can accept. It doesn't matter that it's already a bug. It has to remain safe, and has an impact on language semantics. The sideeffect attribute has a huge performance cost.
2
That's not the consequence of what I said. Rather, unless the safe language has a proof of termination, it marks the function non-pure.
1
If this produces notably worse optimization, it's the fault of the person who wrote the code that doesn't obviously terminate, not the compiler's fault.
1
I say this as someone who's been guilty (in musl) of lots of code with non-obvious logic for termination or satisfying of some other critical invariant, and I want to fix it. Penalizing it with bad performance is a feature. :-)
1
Compilers are extremely bad at proving termination and the issue with the sideeffect intrinsic is it acts as a universal side effect and is not handled by optimizations. It is treated as potentially doing global memory writes, etc. and completely breaks all other optimizations.
So for example, you can have a simple loop over an array based on the length, and the compiler may not be able to tell that terminates since it can't tell that the length of the array isn't changed (even though a human trivially can). If you insert the intrinsic it destroys perf.
2
The compiler can no longer really optimize the loop. It has a universal side effect in each iteration which could do pretty much anything including writing to memory. It's a terrible 'solution' to present for a self-inflicted problem that's easy and straightforward to solve.
1
Show replies

