Hi Rich, On Thu, Jun 19, 2025 at 11:32:09AM -0400, Rich Felker wrote: > On Thu, Jun 19, 2025 at 03:57:47PM +0200, Alejandro Colomar wrote: > > Hi, > > > > Here's a revision of this change, addressing some concerns. I'm only > > showing the formatted changes, since the patch itself is unimportant. > > > > > > Have a lovely day! > > Alex > > > > --- > > $ MANWIDTH=72 diffman-git HEAD > > --- HEAD^:man/man3/malloc.3 > > +++ HEAD:man/man3/malloc.3 > > @@ -126,15 +126,32 @@ > > │ realloc() │ │ │ > > └────────────────────────────────────┴───────────────┴─────────┘ > > > > +VERSIONS > > + The behavior of realloc(p, 0) in glibc doesn’t conform to any of > > + C99, C11, POSIX.1‐2001, POSIX.1‐2008, POSIX.1‐2017, or > > + POSIX.1‐2024. The C17 specification was changed to make it con‐ > > + forming, but that specification was broken —it is impossible to > > + write code that works portably—, and C23 changed it again to > > + make this undefined behavior, acknowledging that the C17 speci‐ > > + fication was broad enough that undefined behavior wasn’t worse > > + than that. > > This is still full of your polemics. The word "broken" generally > belongs in personal blog posts, not a manual that's supposed to be > documenting the facts of an interface.
Hmmm, agree. I've changed the wording: @@ -252,8 +265,10 @@ .SH VERSIONS POSIX.1-2017, or POSIX.1-2024. The C17 specification was changed to make it conforming, -but that specification was broken -\[em]it is impossible to write code that works portably\[em], +but that specification made it +impossible to write code that +reliably determines if the input pointer is freed after +.IR realloc(p,\~0) , and C23 changed it again to make this undefined behavior, acknowledging that the C17 specification was broad enough that undefined behavior wasn't worse than that. > In fact it is very possible to > write code which works portably: by refraining from passing 0. But that entire paragraph is talking about the impossibility to call realloc(p,0) portably. Of course if you call realloc(p,n?:1) it works, because you've avoided the case altogether. > Regardless of what action is taken here on the standards or > documentation, that's already been necessary for a long time, and will > continue to be necessary for a long time, because of the existence of > implementations on which passing 0 has inconsistent results. > > I would suggest something more like: > > The behavior of realloc(p, 0) in glibc doesn’t conform to any of > C99, C11, POSIX.1‐2001, POSIX.1‐2008, POSIX.1‐2017, or > POSIX.1‐2024. C11 was amended in 2017 to allow the glibc > behavior [insert description of exactly how that was done, I > forget] and C23 followed up by making the behavior explicitly > undefined. > > In particular, this text is purely matters of fact, no statement of > your or my preferred future outcome or disagreement with what > happened. > > I would also move it to CONFORMANCE rather than VERSIONS since > VERSIONS is normally about differences between versions of the > implementation being described, not conformance requirement > differences between versions of the standard. Agree. I've moved it to STANDARDS. > > +BUGS > > + Programmers would naturally expect that realloc(p, size) is con‐ > > + sistent with free(p) and malloc(size). This is not explicitly > > + required by POSIX.1‐2024 or C11, but all conforming implementa‐ > > + tions are consistent with that. > > This has not historically been a conformance requirement and it is not > one now. Because the behavior is undefined, arbitrarily-inconsistent > behavior is conforming. This section is about bugs, not about standards. The expectation of programmers is what matters. Since programmers do new = realloc(old, size); if (new == NULL) goto fail; the glibc implementation is causing bugs in user programs, and thus has a bogus implementation. Especially, when it deviates from common historical implementations, which supported the idiom shown above. This is enough to claim it's a bug in glibc. > It's possible to read this as not stating a conformance requirement, > just a matter of fact that all implementations which conform(ed to > past versions of the standard) happened to also be consistent here. Yes. > But in that case I would very much prefer if you make it clear by just > saying that they're consistent on [some explicit list or description > of the class of implementations you've reviewed to have this > property]. I don't fully understand this suggestion. Please clarify. > > > + The glibc implementation of realloc() is not consistent with > > + that, and as a consequence, it is dangerous to call > > + realloc(p, 0) in glibc. > > It's not dangerous if you know what it's doing. Rather it's > non-portable. It does something predictable that you can use safely, > but the way you use it safely is different from other, more consistent > implementations in a way that can be a footgun. It is dangerous, because programmers don't expect the glibc behavior. Please show me a piece of code calling realloc(3) from glibc that does something like this: new = realloc(old, size); if (new == NULL) { if (errno == ENOMEM) free(old); goto fail; } free(new); It is only unnecessary if you know for sure 'size' won't ever be 0, but I bet there's code out there where size might be 0 and they're not doing this. If they're freeing 'old' on NULL without checking for ENOMEM, they're causing a double-free. If they're using old on NULL without checking for ENOMEM, they're causing a use-after-free. That *is* dangerous. > > > + A trivial workaround for glibc is calling it as > > + realloc(p, size?size:1). > > It should probably be noted that use of such a workaround sacrifices > the ability to diagnose logic errors (via sanitizers, valgrind, etc.) > where 1 byte is written to allocated memory that was not intended to > have any accessible bytes of storage. I would note it for n+1, but since n?n:1 would only hide them for the case where size is 0, I find it less problematic. I think adding such text might put off programmers from using this, which would be counterproductive. So, I hope they realize about it without writing it. Have a lovely day! Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature