4 ms·
The standard does make all definable UB implementation defined. The compiler writers intentionally misread the standard to allow these kinds of optimizations.
by torstenvl 3y ago
The standard does make all definable UB implementation defined. The compiler writers intentionally misread the standard to allow these kinds of optimizations.
C17 Draft, § 3.4.3: "Possible undefined behavior ranges from...
. . . ignoring the situation completely with unpredictable results, to . . .
. . . behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message) . . .
. . . to terminating a translation or execution (with the issuance of a diagnostic message)."
Compiler writers like to language-lawyer this in two ways. First, they interpret "possible" to mean that this is a non-exhaustive list, but that isn't how interpretation of such a document typically works. Expressio unius est exclusio alterius -- the express inclusion of one is the exclusion of others -- means that any list is exhaustive unless explicitly indicated otherwise. In other words, the reality is that, according to the standard, these are the only possible options.
Second, they interpret "ignoring the situation completely" to mean "actively seeking out the situation and deleting whole sections of code based on that." This is quite self-evidently a dishonest interpretation.
- lelanthran 3y agoWhile you have convinced me that the compiler authors are more culpable than the standards committee, I still feel that they are ultimately responsible - the buck stops with them. They're free to, and easily able to, add the word "exhaustively" when listing possible behaviours, but they don't. They can even do away with it entirely and replace it with implementation-defined, which makes compilers non-conformant if they optimise out code.
- cesarb 3y agoThe optimization opportunities do indeed come from the first option, "ignoring the situation completely with unpredictable results". That is: the compiler assumes that the undefined behavior will not happen, and optimizes based on it. They do not "actively seek out the situation", it's in fact the opposite, they assume that the situation simply won't happen. And "deleting whole sections of code" is just the normal "unreachable code" optimization: code which cannot be reached on any feasible execution path will be deleted.
- deleted 3y ago[deleted]
- torstenvl 3y agoThat is an obvious misreading. Assume you have an unsigned char array r[] declared with 100 elements and the compiler encounters the following line of code: r[200] = 0xff; "ignoring the situation completely with unpredictable results" means translating that to the appropriate object code without bounds checking and no guarantees are made about whether that's a segfault or what your environment does. "assum[ing] that the situation simply won't happen" means eliding the code entirely. The first is required by the standard. The second is prohibited by the standard. There is no section of any version of the standard that permits compilers to assume that anything which might be UB or predicated on UB is dead code. Compilers must either ignore the fact that it's UB, or behave in a documented implementation-defined manner, or stop translation.
- pdw 3y agoYou're quoting from a footnote. The footnotes are not part of the normative text, so how you choose to interpret it is irrelevant. The actual definition of undefined behavior given by § 3.4.3 is: "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements." Since no requirement is imposed, compilers can do as they want.
- torstenvl 3y ago> You're quoting from a footnote. The footnotes are not part of the normative text I am not quoting from a footnote. Footnote 1 pertains to § 1. Footnote 2 pertains to § 3.19.5. There are no footnotes pertaining to § 3.4.3. And do you have a citation for the proposition that footnotes or notes of any other kind are not normative?
- pdw 3y agoApologies, it's a note, not a footnote. But notes in ISO standards aren't normative either. This is a general principle of ISO standards, see https://share.ansi.org/Shared%20Documents/Standards%20Activities/International%20Standardization/ISO/ISO_IEC_Directives_Part_2.pdf https://share.ansi.org/Shared%20Documents/Standards%20Activi...: > 6.5 Other informative elements > 6.5.1 Notes and examples integrated in the text > Notes and examples integrated in the text of a document shall only be used for giving additional information intended to assist the understanding or use of the document. They shall not contain requirements ("shall"; see 3.3.1 and Table H.1) or any information considered indispensable for the use of the document, e.g. instructions (imperative; see Table H.1), recommendations ("should"; see 3.3.2 and Table H.2) or permission ("may"; see Table H.3). Notes may be written as a statement of fact.
- torstenvl 3y agoI don't view "You shall not do this" and "If you do this, it's meaningless" as identical statements. Besides, clang does the same thing with -std=c89, where this provision was emphatically not a note.