Comment by muvlon

6 hours ago

Fair enough!

> And if it's not succeeded for 54 years, "try harder", or "just never make a mistake", is at least not the solution.

And I 100% agree. UB is way overused by these standards for how dangerous it is, and as a consequence using C (and C++) for anything nontrivial amounts to navigating a minefield.

I think as compilers got smarter, UB changed somewhat in meaning. Originally the compilers didn't perform such complex analysis, and while invoking UB could break your program, it would still do something reasonable.

  • Yes, but compilers got smart enough for it to be a problem around 30 years ago, and we are still arguing about what to do.

What should the behavior above be defined to do?

  • “Implementation defined behaviour”: compiler author chooses, and documents the choice.

    A lot of UB should be implementation defined behaviour instead; this would much better match programmers’ intuitions as they reason about their code - you can even see it in the comments of this post: it’s always things like “this hardware supports / doesn’t support unaligned accesses”, it’s never nasal demons.

  • Print x twice. Not all “side effects” care about order.

    Better yet, define an order for parameter evaluation.

  • Couldn’t you just define that function arguments are evaluated left to right?

    Or just throw an error.

    • Why? Just for this edge case? It could be faster and/or allow smaller code size to allow this to be undefined.

      Undefined is also different from "depends on the compiler", because which behavior is chosen can even depend on the circumstances, whatever code appears before and/or after it.

      That said, UB in code, such as this example of ordering of reads of volatile parameters being undefined, does not automatically mean that code that uses it is bad. It may very well be that the function being called doesn't misbehave either way.