6 ms·
Schrödinger's Code
- hwayne 5y agoOne important piece of historical context this article doesn't talk about: a lot of the undefined behavior in C is there for compatibility, not for optimization. C came out in 1972 while the first official C standard is from 1989. The standard had to be backwards-compatible with all of the major compilers, which had almost 20 years to diverge. That's the source of a lot of undefined and implementation-defined behavior.
- userbinator 5y agoIndeed, the standard even says one of the possible effects of UB is "behaving during translation or program execution in a documented manner characteristic of the environment" and I feel that was really the original intent.
- josephcsible 5y agoThat's the intent for a tiny handful of things that are UB, e.g., "#define _GNU_SOURCE". But for most things, e.g., out-of-bounds array access or use-after-free, it's definitely not.
- userbinator 5y agoThat sounds like revisionism. Look up "spirit of C"... or see what Kernighan and Ritchie said.
- userbinator 5y agoSuch rants have not achieved the desired effect. On the contrary, compiler writers have given notice that they will continue exploiting the liberties granted by the language standards. 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?
- josephcsible 5y agoBecause wanting the fastest code possible is a big reason to use C over some other language, and such aggressive optimizations that break incorrect code are how you get the fastest code possible.
- userbinator 5y agoMy experience with ICC and MSVC contradict that, as well as with handwritten Asm. Instruction selection and scheduling matters far more than trying to be too clever with exploiting UB (and they will remove things like overflow checks, albeit they seem to prove more than assume.)
- gopiandcode 5y ago> The current attitude popular amongst compiler writers is that of strict legality; the term "language-lawyering" certainly applies. 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.
- philipswood 5y agoThis simplifies to: Maybe avoid using C completely and be very careful if you have to.
- 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)
- justshowpost 5y agoThat's the reason one should ALWAYS attend to warnings and even treat them as errors eg. by fixing them
- woliveirajr 5y agoNasal demons, as always [0]. [0] http://catb.org/jargon/html/N/nasal-demons.html http://catb.org/jargon/html/N/nasal-demons.html
- IlliOnato 5y agoIs this really a problem with "infrastructure languages", or just C and C++? Are other "infrastructure languages" plagued by UB? What about D, C#? What about languages which are not "C inspired"?