5 ms·
Are these all undefined rather than merely unspecified or implementation-defined? I'm a little suspicious that they don't explain the difference, but I'm having
by prodigal_erik 10y ago
Are these all undefined rather than merely unspecified or implementation-defined? I'm a little suspicious that they don't explain the difference, but I'm having trouble finding a definitive list of the places where the standard allows nasal demons.
- lomnakkus 10y agoThey're undefined. (From a quick skim.) However, an implementation could define various UBs however it wants. The difference between "undefined" and "implement-defined" is really that an implementation doesn't have to anything even remotely sensible for "undefined" behavior, but it has do define some ("sensible") behavior for "implementation-defined" behavior. Usually, "implementation-defined" behavior also tends to remain consistent across versions whereas "undefined" behavior usually has no such constraints. For example, for "undefined" behavior, version 5.1.2.3 of the compiler may differ drastically from 5.1.2.4 in terms of optimizations which rely on UB.
- Sharlin 10y agoBasically: Undefined - the compiler may assume this can never happen, and if it does happen, it can "poison" the whole execution including whatever logically happens before the undefined part. Unspecified - the behavior must be deterministic and cannot affect the semantics of other well-defined parts of the program, but the implementation need not guarantee any single behavior. Implementation-specified - like above, but the implementation must specify the exact behavior.
- to3m 10y agoThe compiler may also assume undefined behaviour can happen, and do something documented, that programmers would probably expect. Even though the standard imposes no specific requirements, it explicitly calls that out at something you could do: http://port70.net/~nsz/c/c11/n1570.html#3.4.3 http://port70.net/~nsz/c/c11/n1570.html#3.4.3 But for some reason nobody seems to ever think this is an option.
- lmm 10y agoIt wouldn't improve benchmark performance, which is what C compiler writers care about. And at this point in time any programmer who wants that kind of behaviour has probably moved on from C.
- lomnakkus 10y agoWell, that and undefined behavior sometimes would require absurd amounts of runtime checking (eg. on signed bit shifts, etc.).
- aargh_aargh 10y agoSince I didn't get the reference, here's the explanation: http://catb.org/jargon/html/N/nasal-demons.html http://catb.org/jargon/html/N/nasal-demons.html
- mattkrause 10y agoI love the mental image, but I think that description masks why this happening. The compiler doesn't specifically search for undefined behavior and use it as an excuse to do something "quirky." Instead, it assumes the code is well-defined and interprets (and transforms) it in ways that preserve its semantics. For example, "One cannot dereference null pointers. The author dereferenced the pointer p. Therefore, p is not null. Since p is not null, the compiler can avoid checking it after the first dereference." The compiler is essentially assuming that the author knows something that it may not and just runs with it. However, there are a lot of transformations--and corner cases--many of which can interact. This can produce complex unwanted behavior that looks like "nasal demons", but largely as a side effect. The compiler does not say "OVERFLOW DETECTED. REPLACING ENTIRE FUNCTION WITH NOOP"
- scott_s 10y agoI looked this up about a year ago: https://news.ycombinator.com/item?id=10840497 https://news.ycombinator.com/item?id=10840497