3 ms·
> A different philosophy reigns in domains that demand efficiency and speed (e.g., infrastructure software). Systems programming languages such as C and C++ sac
by Sniffnoy 5y ago
> A different philosophy reigns in domains that demand efficiency and speed (e.g., infrastructure software). Systems programming languages such as C and C++ sacrifice safety and comprehensive semantics for performance. These languages, despite being meticulously standardized, do not define the behavior of all code that compiles.
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.
- ithkuil 5y agoThere is undefined behaviour and there is Undefined Behaviour. 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)
- Google234 5y agoundefined behaviour and Undefined Behaviour are the same thing… How would the standard define behavior that depends on the implementation. All they say for UB is that there are no requirements for what will happen. How would your perfect language deal with a branch depending on some uninitialized boolean value?
- ithkuil 5y agoIt doesn't! That's the whole point I'm trying to make (poorly). 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.