7 ms·
I'm not convinced. The argument seems to hinge to a very large extent on the sentence: > Permissible undefined behavior ranges from A, to B, to C. The observa
by tom_mellior 5y ago
I'm not convinced. The argument seems to hinge to a very large extent on the sentence:
> Permissible undefined behavior ranges from A, to B, to C.
The observation that "Permissible" has a specific meaning is important and interesting. But what about "ranges from ... to ..."? The author reads this as "Permissible undefined behavior is either A or B or C.", but that seems like a stretch to me. (Unless ISO defines "ranges" to mean just this.)
Also, in the above, A = "ignoring the situation completely with unpredictable results". Both "ignoring" and "unpredictable" do a lot of heavy lifting here. In the signed integer overflow case discussed in the linked GCC bug report (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475), one could very well argue that "ignoring" a case where signed arithmetic overflows is exactly GCC is doing. It "ignores" the possibility that a + 100 might overflow, hence obviously a + 100 > a is true, leading to results that the reporter considers "unpredictable". Somehow the author seems to think that this is not what the wording intended, but they also fail to explain what they think should happen here.
Sounds to me like the wording has always been very vague.
Also:
> Returning a pointer to indeterminate value data, surely a “use”, is not undefined behavior because the standard mandates that malloc will do that.
Yes, malloc will do that, but using a pointer to indeterminate data is not the same as using the indeterminate data itself. The author is doing themselves a disservice by misreading this.
- hedora 5y agoThe original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then). On x86, the correct behavior was previously (and obviously) “perform a 2s complement wraparound”. To “ignore” the situation used to mean “delegate to a lower level”. It now means “silently generate code that violates the semantics of the target microarchitecture” As the article argues, I think this has gone too far. For example, people are starting to claim that asm blocks are undefined behavior. They’re clearly implementation specific (so undefined by the spec), but also well defined by each implementation. In current readings of the spec, compilers are free to ignore them completely. Doing so would break all known operating systems, and many user space programs, so they have not managed to do so yet. Edit: for signed overflow, other architecture-specific behavior (such as optionally trapping floating point exceptions) would also have been permissible, assuming the architecture supported it.
- jcranmer 5y ago> The original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then). The term for that is implementation-defined, not undefined. If it were to be architecture-specific, back in C89, they would have used the term implementation-defined, as they do for things like the size of pointers.
- anarazel 5y agoThere's "implementation defined" for the concept you describe.
- Jiro 5y ago>Somehow the author seems to think that this is not what the wording intended, but they also fail to explain what they think should happen here. What "should" happen is that the implementation-defined behavior in the assert matches the implementation-defined behavior in the calculation. That is, assert(a+100>a) should produce the same result as int x = a + 100; int y = a; if (x > y) ; else printf("assertion failed\n");
- richardwhiuk 5y agoThat behaviour is no less undefined in the process of overflow.
- Jiro 5y agoOkay, then let's rephrase without a code example: The implementation-defined behavior in the assert should produce "true" if and only if the number printed for x+100 (also using implementation-defined behavior) is always larger than the number printed for x.