You keep using that word. I don't think it means what you think it means. :)
To put that another way, you can treat certain behaviors as if they're opaque functions until after you're done optimizing. Similar to how you might handle volatile.
Some of these changes would be very easy. For example, instead of treating "dereference zero" as unreachable code, treat it the same as "dereference unknown location".
Where your problem lies is what happens when you optimize that code. And guaranteeing optimizations do something superficially sane on unsound code while still performing reasonable and obvious optimizations for well-formed code is insanely hard.
The fundamental problem is that the design of C guarantees that lots and lots and lots of syntactically valid and intuitively written code is semantically total nonsense. Part of this is that C is low-level and part is just that it was designed 50 years ago before anyone had the faintest idea what kinds of terrible mistakes were being made.
If there were simple fixes here it wouldn’t still be a problem.
It really depends on the type of optimization.
A lot of the scariest results come when the compiler treats code as dead, and in very many cases you could go ahead and emit the code anyway and performance would be fine.
> If there were simple fixes here it wouldn’t still be a problem.
Nobody is trying to reduce the scope of UB, though. Even things that are very easy to define or implementation-define like syntax errors or left shifting with certain parameters are still sitting on the list.
The number of elements of the set of real numbers between 1 and 2 is undefined, but we can say with absolute certainty that 3.5 isn't one of them.
void (*f)() = (void (*)())rand();
f();The compiler could behave in a documented manner with or without a warning; it could error out and stop translation; or it could do what you fracking told it to, consequences be damned.
> or it could do what you fracking told it to, consequences be damned
Yes, that's precisely what happens. The point is agreeing on what you "told it". The agreement stipulated in the standard is that in some cases (when you hit UB) you're effectively not agreeing on anything, i.e., the compiler can do what it want.
If that's not what you like, please let me know what should be mandated in the case of the fragment I wrote above, and how a compiler could offer that guarantee in an efficient and effective manner.
> that's precisely what happens
No, it really isn't. Numerous compilers do static analysis to identify code that could be UB and then mangle it to mean something entirely different or eliminate it entirely. And if the compiler really did already do this, you wouldn't need to resort to...
> the compiler can do what it want[s]
Under current standards, yes, but that's a circular and nonsensical argument. You can't base your argument on what the standard permits when the very content of what the standard should be is the topic of discussion.
> please let me know what should be mandated
I already responded. The ANSI C standard is clear, and the modification to that language in subsequent ISO standards is, in my opinion, ill-advised.