5 ms·
If anything's messed up, then that would be my doing. I thought at first that some of the words in the piece were distorted as a joke about undefined behavior,
by nkurz 10y ago
If anything's messed up, then that would be my doing.
I thought at first that some of the words in the piece were distorted as a joke about undefined behavior, but as I look at the source, I think something is just broken with the custom fonts.
If signed overflow were defined, then 12 * i + 8 would have to have correct overflow behaviour for 32-bit values and so this trick couldn't be done.
I feel like this misses the difference between "undefined" and "implementation defined". Despite the example given, those of us (like me) who complain about compilers removing safety checks rarely claim that signed 32-bit ints must have guaranteed behavior on overflow. Overflowing might be easiest, if that's what the hardware does naturally, but it doesn't have to be defined to do this.
In our minds, it would be just fine for the compiler to generate an "add" instruction and let the registers fall where they may. What we object to is the compiler's reasoning that since "undefined behavior can be presumed not to occur, I'll just delete this spurious NULL check that the programmer accidentally put here".
Granted, there are cases where a compiler can take proper advantage of such optimizations, but it's emphatically not the case that the only alternative to the current "nasal daemon" approach is disabling all loop optimizations. Simply changing "undefined" to "implementation defined" would satisfy a majority of the objections.
- pascal_cuoq 10y agoThis post, written by someone who is or has been on the standardization committee gives a different point of view: http://shape-of-code.coding-guidelines.com/2014/08/31/undefined-behavior-pay-up-for-shut-up/ http://shape-of-code.coding-guidelines.com/2014/08/31/undefi... What always surprises me is that, when a new optimization comes out justified by a sentence in a dark corner of the C standard, you can usually trace the sentence back all the way to C90.
- Kristine1975 10y ago>the members of the committee were rubbing their hands at the thought of all the optimizations the poorly specified ambiguous successive versions of the document would allow: I couldn't find that in the blog post you linked?
- deleted 10y ago[deleted]
- pascal_cuoq 10y agoYou are right. Either I was thinking of another comment by Derek Jones (one of the two persons I know on the C standardization committee, which is otherwise quite opaque) or I projected my own image of a patiently malevolent committee on the phrase “doing stuff that we could only dream about back in the day” that he did not mean this way. I have edited my comment.
- pcwalton 10y ago> Granted, there are cases where a compiler can take proper advantage of such optimizations, but it's emphatically not the case that the only alternative to the current "nasal daemon" approach is disabling all loop optimizations. Simply changing "undefined" to "implementation defined" would satisfy a majority of the objections. No. Since a huge number of loop optimizations are dependent on trip count detection, this is not in fact the case. Loop trip count detection is ruined by making signed overflow implementation defined. See this thread from just last week explaining this: https://news.ycombinator.com/item?id=11653940 https://news.ycombinator.com/item?id=11653940 Additionally, there's less of a difference between "undefined" and "implementation defined" than you might think. Consider the example in the original post: if (x + y < x) { return 0; /* Overflow */ } length = x + y; With implementation defined overflow, the compiler is still free to remove this check, because the value of "x + y" would become an undefined value on overflow, and comparisons on undefined values are themselves undefined. If you want the compiler to do anything else, then you're proposing a drastic overhaul of (for example) LLVM's notion of "undef" [1], one that would have massive consequences for optimization. [1]: http://llvm.org/docs/LangRef.html#undefined-values http://llvm.org/docs/LangRef.html#undefined-values
- nkurz 10y agoSince a huge number of loop optimizations are dependent on trip count detection, this is not in fact the case. Loop trip count detection is ruined by making signed overflow implementation defined. Could you offer a good example of a loop where performance of a human written lop would suffer if the loop counter was changed from int64_t to uint64_t? I'm sure they exist, but I wonder if I'm underestimating the severity. With implementation defined overflow, the compiler is still free to remove this check, because the value of "x + y" would become an undefined value on overflow Well, no, at least the way I'm viewing "implementation defined". If the signed addition is implementation defined, I'd think that by definition "x + y" never becomes an undefined value. As I'm sure you realize (but others might not), x64 doesn't have separate add-signed-32-bit and add-unsigned-32-bit instructions. So on x64, I'd hope that a sane implementation would simply define signed addition as "ask the processor to add x to y and interpret the result as signed". I don't think this would require any overhaul of the notion of "undef"?
- caf 10y agoIf signed addition were implementation defined to be saturating, then if (x + y < x) could still be removed as impossible.
- StefanKarpinski 10y agoYes, but in that case there wouldn't actually be an overflow either.