Schrödinger's Code
queue.acm.org
queue.acm.org
This is really just a problem with C and C++, though, not systems programming in general. Obviously those are the most popular languages for it, but that's something of an accident; it's not due to their use of undefined behavior. If anything their use of undefined behavior may be beginning to drive people away, and famously the Linux kernel uses special compiler settings to turn off some such optimizations.
Moreover, as already noted by hwayne in another comment, undefined behavior was originally primarily for compatibility purposes; compilers didn't begin exploiting it for (expected-semantics-destroying) speedups until much later.
So, I think it is a mistake to frame the dispute in this way, identifying systems programming with being pro-undefined-behavior. It seems to me that the "school of thought" (not actually a school of thought) that says that behavior should be predictable from source encompasses most systems programmers too.
The Undefined Behaviour that is plaguing C is when the spec says that this or that condition can never happen and thus the compiler can freely assume it can never happen (and emit code under that assumption) and when a programmer actually writes a program that violates those (often subtle) rules the compiler authors say "screw you! You shouldn't have written such program, haven't you read the specs?".
Now imagine a language whose spec isn't full of such traps, but ensures compiler don't surprise authors (e.g. by deleting code that checks for invariants and other things that plague people working with languages with Undefined Behaviour).
Now also imagine that such language is a system language that needs to strike a tradeoff between safety and performance and imagine that the choice falls in letting memory corruption to happen in some edge cases.
Such language (which exists) is devoid of Undefined Behaviour, than goodness, but the programs it emits can still exhibit undefined behaviour, i.e. once a memory corruption occurs you can of really predict what the program will do (since the details depend on the dynamic content of the memory which may change between one run to the next).
Those two kinds of undefined behaviour are not at all the same. With the latter you can still debug such a program. The compiler didn't conspire against you. You can step through the code (even backwards in a reverse debugger) and deterministically analyze what happens after the memory is corrupted in one way or another.
With C/C++'s Undefined Behaviour your source program has been butchered, it's no longer what you wrote. Surely you can debug the resulting machine code (which will behave deterministically) but it's not your code, it's allowed to depart from what you wrote in significant ways. And that's not a bug, it won't be fixed by compiler authors, and that's what makes it endlessly frustrating.
But that said, many programming languages can produce programs that at runtime hit a circumstance after which you cannot really reason about it. It's just that the compiler is not actively conspiring against you to make it even harder than what it should be.
EDIT: since the term undefined behaviour is so overshadowed by Undefined Behavior, people sought alternative names, with tho goal of reassuring users that this is not Undefined Behaviour we're talking about.
A common alternative name for that is "unsafe" (safe as in memory safety)
People are not hating that (existing, popular, but unnamed here to avoid distraction) language because in practice that problem doesn't bother people at the same level that it bothers with C/C++! Why? Because the compiler is not actively exploiting each bad step you make.
I think this is one of the reasons why discussing undefined behaviour is so confusing. From a technical/purist point of view, it clearly means something and once the behaviour is undefined, it is undefined and yadda yadda. But in practice it makes a huge difference, to the point that people tried to coin a new name for it (e.g. "unsafe code"), while it is the same thing.
That suggests to me that the opposition to this exploitation needs to be even stronger...
To take this whole discussion in a philosophical direction, I see the two sides of the argument as having a real-world analogy to laws vs. morals and ethics. The current attitude popular amongst compiler writers is that of strict legality; the term "language-lawyering" certainly applies. But like the real-life analogy, what is legal is not necessarily moral or ethical, and vice-versa. There's a lot of discussion on other topics, here and elsewhere, where that idea is highly debated --- someone will post something along the lines of "but what they're doing is legal", and then many replies will elaborate why that is still wrong.
Yet for some reason, when C and UB comes up, for some reason it seems not agreeing with those ruthlessly exploiting the standard and belittling everyone who dares question them is a highly unpopular and controversial opinion?
The difference is that morality is inherently subjective whereas a programming language is pretty much the exact opposite - it is /exactly/ defined by its specification. You may disagree with the design of the language (which is subjective), but that is strictly different from "language-lawyering" and determining what is and isn't allowed by the specification as it is objectively written.
> Yet for some reason, when C and UB comes up, for some reason it seems not agreeing with those ruthlessly exploiting the standard and belittling everyone who dares question them is a highly unpopular and controversial opinion?
Barring the rather unreasonable characterisation of compiler writers as "exploiting" and "belittling" developers, if people have a problem with compiler writers optimizing to the extents allowed by the programming language, then the place to voice these concerns is not through opposition to the compiler writers (who are just doing their job), but to the standards committee writing the specification for the language.