Hacker News new | ask | show | jobs
by nayuki 723 days ago
Your reasoning is incorrect. Here is how I reason about it.

Division by zero is undefined behavior. The compiler can assume that it will not happen.

If the divisor is not zero, then the calculation has no side effects. The compiler may reorder the division above the print, because it would have no observable difference in behavior. This could be useful because division has a high latency, so it pays to start the operation as soon as the operand values are known.

If the divisor is zero, the UB says that there is no requirement on how it's compiled, so reordering the division above the print is legal.

2 comments

  const int div = 0;
  if(div) { 
    return 1/div;
  }
  return 0;
The statement at line 3 would have undefined behaviour, yet is never reached so this is a perfectly legal program and any transformation that hoists it above the check is invalid.

If you replace 'if(div)' with an opaque function call, that doesn't change anything as the function might never exit the program, never return, long jump or return via an exception.

How can it both have no side effects and have undefined behaviour?
By being declared as that?

Division has no side effects, and division by 0 is UB. UBs only occur in invalid programs, so behaviour in case of UB is not relevant to a discussion of side effects or their lack thereof, in language terms these are not programs at all.

If print statement never completes then it is a well defined program. Because there will be no division by zero.
And if my grandmother had wheels she'd be a bike.
Is your grandmother a bike every time the receiving side of a pipe terminates before the sending side, or only when it happens to interrupt a printf?
Both statements don't need to be true. The compiler just has to prove that at least one of the statements will always be true.
True but it only has no side effects if it's well defined. The compiler can assume it's well defined but only if it's executed.