3 ms·
The author of the paper is not competent in the subject matter. A compiler can make assumptions that behavior is well defined, and it can also identify situati
by kazinator 2y ago
The author of the paper is not competent in the subject matter.
A compiler can make assumptions that behavior is well defined, and it can also identify situations where it is confirmed undefined.
All of that reasoning happens before runtime.
For instance, and unreachable assertion works by invoking undefined behavior. What identified by the function-call-like syntax unreachable().
If we have:
S; unreachable();
then, ostensibly, it looks as if statement S is something that happens at run time before the unreachable construct is executed. (S is a simple statement which passes control to whatever follows; it does not hide a go to).
And so we could naively argue that undefined behavior cannot travel backward in time. Of course S must successfully execute, and only then can things go haywire due to the undefined behavior of unreachable.
But that's not the way it works. The compiler is looking at this before runtime. The compiler is free to assume that behavior is well defined. That's what makes unreachable work: if the program's behavior is well defined, it must be that the unreachable statement is never reached. Which implies that S is never executed. If S is never executed, it can just be deleted.
If S and the unreachable statement are deleted, but control ends up there anyway, the program will go haywire. And it will go haywire without producing the effects of S. So in effect undefined behavior has gone backwards into S, so to speak in naive language.
Logical reasoning over code while translating it does not follow runtime chronology. It follows chains of inferences.
- CRConrad 2y ago> The author of the paper is not competent in the subject matter. Yeah, sure, quite possible (I have no idea). But then he needs to be kicked out explicitly for not being competent in the subject matter. Because kicking him out (at least ostensibly) for a ridiculous made-up language issue sets the precedent that people can -- should? -- be kicked out for ridiculous made-up language issues. I mmean... Isn't that the point of this whole thing? Which makes your technical qu-- well, sure, perhaps your quite valid technical issues, but in the context of him being kicked out ostensibly for some totally different and definitely invalid "reason", a quibble -- isn't your point then rather irrelevant to the actual point of the discussion?
- uecker 2y agoAs 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)
- kazinator 2y agoObservable 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?
- uecker 2y agoFor: 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.
- kazinator 2y agoIt'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.