3 ms·
I don't disagree, but I feel "code that checks the value of the divisor prior to a division can be removed by a compiler" needs clarification: it's not as insan
by moefh 8y ago
I don't disagree, but I feel "code that checks the value of the divisor prior to a division can be removed by a compiler" needs clarification: it's not as insane as it sounds.
The example given in the referenced paper[1] for this is:
if (arg2 == 0)
ereport(/* ... */);
PG_RETURN_INT32((int32) arg1 / arg2);
The compiler re-ordered the instructions and performed the division before the check, but only because it didn't know "ereport()" couldn't return (so the compiler thought the division would happen either way). If the code had been:
if (arg2 != 0)
PG_RETURN_INT32((int32) arg1 / arg2);
ereport(/* ... */);
or something like it, it would have been fine.
[1] https://people.csail.mit.edu/nickolai/papers/wang-undef-2012-08-21.pdf https://people.csail.mit.edu/nickolai/papers/wang-undef-2012...
- radford-neal 8y agoI think that's just a compiler bug.
- moefh 8y agoNah, it's a valid optimization as long as ereport() returns. The compiler doesn't need to follow the order of operations as long as the observed behavior is the same as if the operations were performed in the order in the code. Since the compiler doesn't have any responsibility if division by zero happens, it's fine to do the division before. This is an interesting read: https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633 https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=...
- Asooka 8y agoIt is a compiler bug. The compiler can't reason what the effect of dividing by zero will be, because it's undefined. Therefore, hoisting the division before the if can change the observed behaviour, because the ereport function won't be executed. Ereport may not return, or it may print a debug message, or any other manner of things that are absolutely observable program behaviour. The function should be compiled with whatever division opcode or subroutine the compiler likes, including ones that crash the program, make it loop forever, make your cpu explode, or launch nukes at North Korea, however - it cannot reorder the function call after the division, because if it crashes, the program behaviour changes.
- lisper 8y ago> it cannot reorder the function call after the division Actually, it can because one of the things undefined behavior can do is go backwards in time. Undefined behavior anywhere in the program can legally make any part of the program do anything at any time. On top of that, there is no reliable way to tell if your program contains undefined behavior. This is madness.
- nickpsecurity 8y agoOn that last point, check out Rosu et al's KCC: an executable, formal semantics of C that addresses undefined behavior. https://github.com/kframework/c-semantics/blob/master/README.md https://github.com/kframework/c-semantics/blob/master/README...
- comex 8y agoSee my response to a sibling comment of yours making a similar point. It can only go back in time to a point where execution of undefined behavior is inevitable; it doesn’t count if the program aborts first: https://news.ycombinator.com/item?id=16917302 https://news.ycombinator.com/item?id=16917302
- jjnoakes 8y ago> Undefined behavior anywhere in the program can legally make any part of the program do anything at any time. This is only true if the undefined behavior is guaranteed to be reachable. This is not true in general. Putting "if (0) 1/0;" in a program does not cause undefined behavior.
- lisper 8y ago> This is only true if the undefined behavior is guaranteed to be reachable. Nope. It's true if the UB is possibly reachable. See: https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633/ https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=...
- 8y ago