back

by uecker·1y ago·view on hn ↗
As it is based on my C paper, I can comment on this. While the compiler reasons at translation-time the question is whether an operation that UB is allowed to affect previous observable behavior at run-time. We looked at this and came to the conclusions that 1) the wording of the C standard never really allowed this (but the C++ standard did), 2) it is completely useless for worthwhile optimizations, 3) examples where compilers exploited this intentionally turned out to be buggy, 4) it makes UB even more dangerous. So we made sure the C standard clarifies that UB can not travel backwards in in time.

I agree the title of the paper is unfortunate. I do not believe the author was intentionally trying to send an antisemitic message, but I do not know him well (I corresponded with him about his other paper)

1 comments
Observable behavior is a formal concept: a normative term in ISO C.

If statement S has observable behavior, then that may not be removed by an optimization.

But if S is declared as not being reached, does it still have observable behavior?

Is my example considered a case of UB affecting prior observable behavior? Why or why not?

For:

  A; // observable
  B; // UB
and when A is reachable, the compiler can not remove A even if it sees at compile-time that B has UB when executed. This is the case in C but not in C++.

If A is not reachable, the code will never be executed at run-time, so while there is no UB at run-time this is irrelevant as the code can simply be removed anyway because it is not reachable. For "unreachable()" the question is tricky and I think this might need to be clarified specifically.

It's not tricky though. Unreachable invokes UB. It's something like the most canonically reduced version of B that we can write.

(Because unreachable is meant to be used in certain ways, implementations can give it relevant diagnostic powers. But all it means "please make the spot in the program have no defined behavior").

If the implementation cannot remove A on grounds of B being undefined, then you need an awkward special case for when B is the unreachable gizmo.

It is tricky because it not specified simply as UB - at least in C. And the question is whether this specification is already the special case or not, and even if we want this special case or rather only the diagnostic.