4 ms·
I would argue it's the modern understanding of C standard is flawed. Back in 89, many of those unspecified behavior were understood as implementation/hardware
by j16sdiz 3y ago
I would argue it's the modern understanding of C standard is flawed.
Back in 89, many of those unspecified behavior were understood as implementation/hardware dependent, not undefined. Aliasing was the norm, `restrict` was actually a keyword.
Modern C is neither safe nor low-level.
- jcranmer 3y agoAscertaining the state of the mind of the C committee in 1989 is difficult, since only the documents from ~late 1996 are consistently available online (the earlier documents are probably sitting somewhere in a warehouse in Geneva, but they may as well not exist anymore). But definitely by the time C99 came out, it is clear that optimize-assuming-UB-doesn't-happen was an endorsed viewpoint of the committee [1]. C99 also added restrict to the language (not C89 as you suggest), and restrict was the first standardized feature that was a pure UB-optimization hint [2]. It is important to remember that there isn't just one catch-all category of implementation-varying behavior. There is a difference between unspecified behavior, implementation-defined behavior, and undefined behavior. Undefined behavior has been understood, from its inception, as behavior that doesn't constrain the compiler, and often describes behavior that can't be meaningfully constrained (especially with regards to potentially-trapping operations). [1] The C99 rationale gives an example of an optimization that compilers can perform that relies on assuming UB can't happen--reassociation of integer addition, on one's complement machines. [2] The register keyword is I believe even in K&R C and would also be qualified as a compiler hint feature, but I note that it prohibits taking the address of the variable entirely, so it doesn't rely on UB. Whereas restrict has to rely on "if these two variables alias, it's UB" to allow the compiler to optimize assuming nonaliasing.
- Someone 3y ago> Back in 89 […] `restrict` was actually a keyword. Was it? I thought it’s more recent. https://en.wikipedia.org/wiki/Restrict https://en.wikipedia.org/wiki/Restrict seems to agree (“In the C programming language, restrict is a keyword, introduced by the C99 standard,[1] that can be used in pointer declarations”), as does https://en.cppreference.com/w/c/language/restrict https://en.cppreference.com/w/c/language/restrict (“restrict type qualifier (since C99)”) Was there an older usage?
- rsaxvc 3y agoI've used several pre-C99 embedded compilers that supported restrict. IIRC, probably of mid 90s vintage.
- 6D794163636F756 3y agoI haven't gotten to use C in industry, but I was taught that undefined behavior just means that it is defined by the running system and not the compiler. Is that not the general understanding? Maybe I was just taught that way because it was old timers teaching it.
- dale_glass 3y agoNo. See this for details on how UB is handled by compilers: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-... The TL;DR is that compilers compile code based on assumptions that UB won't be invoked. This sometimes produces extremely surprising results which have nothing to do with the hardware/OS.
- School-Cotton 3y agoThat’s indeed incorrect. Undefined behavior anywhere means that the entirety of your program is undefined and may do anything.
- patrakov 3y agoWhat you are talking about is implementation-defined behavior. It exists in the C standard separately from the undefined behavior.
- SAI_Peregrinus 3y agoImplementation Defined behavior means the standards authors provided a list of possible behaviors, and compiler authors must pick one and document which they picked. Unspecified behavior is more what you're thinking of, though in that case the standard still provides a list of possibilities that compiler authors have to pick from, they just don't have to document it or always make the same choice for every program. There's no allowed subset of behavior where compiler authors are free to pick whatever they want and document it (but must do so). IMO there should be, most "Undefined Behavior" could be specified and documented, even where that choice would be "the compiler assumes such situations are unreachable and optimizes based on that assumption" like much of current UB. At least it'd be explicit!