Path: csiph.com!1.us.feeder.erje.net!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.std.c Subject: Re: Does reading an uninitialized object have undefined behavior? Date: Thu, 03 Aug 2023 15:20:14 -0700 Organization: None to speak of Lines: 101 Message-ID: <871qgjlqe9.fsf@nosuchdomain.example.com> References: <87zg3pq1ym.fsf@nosuchdomain.example.com> <864jlfj34p.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Info: dont-email.me; posting-host="ad89738ee6b746bb8bd9b1180a09fd6e"; logging-data="1002229"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+vBu8gjAYem7GPAePrMqSn" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:Djk9iKvEsy51fvHLKxPeb2QufXs= sha1:b7dosTQNRwf5ZIpsSyvJZdL7Hng= Xref: csiph.com comp.std.c:6526 Tim Rentsch writes: > Repeating the question stated in the Subject line: > > Does reading an uninitialized object [always] have undefined > behavior? > > Background: Annex J part 2 says (in various phrasings in > different revisions of the C standard, with the one below > being taken from C90): > > The value of an uninitialized object that has automatic > storage duration is used before a value is assigned [is > undefined behavior] (6.5.7) > > Remembering that Annex J is informative rather than normative, > is this statement right even for a type that has no trap > representations? To ask that question another way, is this > statement always right or is it just a (perhaps useful) > approximation? [400+ lines deleted] > Summary: my reading is that accessing an object that has not > been explicitly stored into since its declaration was evaluated > is necessarily undefined behavior in C90, but not necessarily > undefined behavior in C99 and C11 (and AFAIAA also in C17 and > the upcoming C23). My reasoning is given in detail above. > > > Postscript: this commentary has taken much longer to write than > I thought it would, for the most part because I made an early > decision to be systematic and thorough. I hope the effort has > helped the readers gain confidence in the explanations and > conclusions stated. I may return to the deferred topic about > pointer types but have no plans at present about when that might > be. Thank you for taking the time to write that. I'd like to offer a brief summary of the points you made. Please let me know if my summary is incorrect. - An "indeterminate value" is by definition either an "unspecified value" or a "trap representation". - In C90 (which did not yet define all these terms), accessing the value of an uninitialized object explicitly has undefined behavior. - In C99 and later, J.2 (which is *not* normative) states that using the value of an object with automatic storage duration while it is indeterminate has undefined behavior. This implies that: int main(void) { int n; n; } has undefined behavior, even if int has no trap representations. - Statements in J.2 *should* be supported by normative text. - There is no normative text in any post-C90 edition of the C standard that supports the claim that reading an uninitialized int object actually has undefined behavior if it does not hold a trap representation. (Pointers raise other issues, which I'll ignore for now.) - The cited statement in J.2 is incorrect, or at least imprecise. I agree with you on all the above points. There is one point on which I think we disagree. It is a matter of opinion, not of fact. You wrote: Remembering that Annex J is informative rather than normative, is this statement right even for a type that has no trap representations? To ask that question another way, is this statement always right or is it just a (perhaps useful) approximation? The statement in N1570 J.2 is: The behavior is undefined in the following circumstances: [...] - The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.9, 6.8). I get the impression that you're not particularly bothered by the fact that the statement in J.2 is merely an "approximation". In my opinion, the statement in J.2 is simply incorrect, and should be fixed. (That's unlikely to be possible at this stage of the C23 process.) The fact that Annex J is, to quote the standard's foreword, "for information only", is not an excuse to ignore factual errors. Readers of the standard rely on the informative annexes to provide correct information. This particular text is not just a "(perhaps useful) approximation"; it is actively misleading. I'm not criticizing the author of the standard for making this mistake. Stuff happens. It was likely a result of an oversight during the transition from C90 to C99. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */