Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: C wish list Date: Mon, 25 Mar 2019 13:40:04 -0700 Organization: None to speak of Lines: 65 Message-ID: References: <18RkE.296542$DH4.255445@fx24.am4> <1d54b052-49e7-4aee-a4cc-a394a0a77886@googlegroups.com> <7499c550-d259-4c17-8e99-d88c51cfd83a@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="784bbd8fb1c90ff7036d4663e7b2295d"; logging-data="3087"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+V2jCSGJJWkO/H4F2Kc4/u" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:CbvWBcYUWPgfYiuWkeQZrbhYbcE= sha1:bctAQcLTq7WfVd7Fwx6b2CviQ2Q= Xref: csiph.com comp.lang.c:142439 Howard Chu writes: > On Monday, March 25, 2019 at 11:59:12 AM UTC, Richard Damon wrote: >> On 3/25/19 12:54 AM, Keith Thompson wrote: >> > Howard Chu writes: >> > [...] >> >> The rule that pointers from different objects can't be compared is somewhat >> >> meaningless. The malloc and free functions need to be able to compare their >> >> arguments against their heap boundaries, at least. And for that to be legal >> >> for them to do, the heap itself must be a single character array. But if the >> >> heap *is* a single character array, that means that all pointers returned >> >> from malloc are actually part of a single object, and thus should be legal >> >> to compare to each other, regardless of what kind of structure/type the >> >> caller uses them for. >> > >> > The heap might be *implemented* as a single character array, but it's >> > not an object as far as C is concerned. This code fragment: >> > >> > char *a = malloc(1); >> > char *b = malloc(1); >> > a < b; >> > >> > has undefined behavior (unless, I think, one of the pointers happens >> > to point just past the object pointed to by the other pointer) -- >> > regardless of how malloc is implemented. >> > >> >> The behavior is defined IF the heap did start as a single array, so that >> the pointers are all part of a single object. Since we, as users of the >> implementation, don't know that for sure, we can't depend on it. The >> implementer of malloc, might know that it is true, and could then depend >> on that fact. > > The compiler can't know at compile time either, if whatever malloc > implementation you choose to use does this or not. The spec is wrong > to unconditionally declare this as undefined behavior, thus forcing > users to avoid pointer comparisons that could be perfectly valid on a > given implementation. The compiler is part of the implementation, and it can make assumptions about the rest of the implementation. The user generally doesn't get to choose which runtime library implementation is used.; That's up to whoever creates the C implementation and that person or group has the responsibility of making the whole thing conforming. A compiler *could* take advantage of knowledge that malloc allocates from a single static array, and therefore that `a < b` won't do something strange. Since the behavior of `a < b` is undefined by the standard, the compiler can do anything it likes -- including behaving sensibly. An implementation's documentation could state that the `a < b`, where a and b are both values returned by malloc, will always yield 0 or 1 in a consistent manner (a < b && b < c implies a < c, for example). That's not something that the standard requires the implementation to document. A user of that implementation can reasonably rely on that guarantee *when using that implementation* -- but if the documentation lies, the user's quarrel is with the implementer; it doesn't make the implementation non-conforming. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */