On Wed, Jun 25, 2025 at 03:58:31AM +0200, Alejandro Colomar wrote: > Hi! > > Here's a revision addressing a few things: > ... > Rationale
> > However, this doesn't need to be like that. The traditional > implementation of realloc(3), present in Unix V7, inherited by > the BSDs, and currently available in range of systems, including > musl libc, doesn't have any issues. glibc --which an > independent implementtion, not a Unix derivative-- also had this Typos. Maybe: glibc --which uses an independent implementation rather than a Unix derivative-- > behavior originally; it changed to the current behavior in 1999 > (glibc 2.2), only for compatibility with C89, even though > ironically C99 was released soon after and made it > non-conforming. glibc 2.2 was released Nov 2000; the change to realloc made it into 2.1.1 of May 1999. Elsewhere, you are clear that it it glibc <= 2.1 that has the old behavior. Maybe it's worth being more precise to name it glibc 2.1.1 here (yes, I know that Paul Eggert originally mentioned 2.2 in this thread and I've carelessly copied that value; I guess this is evidence that glibc's version numbering policy has changed slightly over the years). I'm still not completely convinced that C99 declares the glibc behavior to be non-conforming. On the one hand, it does have the escape clause of "If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object." in 7.20.3, with no clause requiring a null pointer return to be treated as an error. On the other hand, it has both of these sentences on realloc proper in 7.20.3.4: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated." So if you can argue that a null pointer being returned MUST imply allocation failure, it logically follows that allocation failure MUST imply the original pointer was not deallocated (but glibc deallocated that pointer, hence non-compliance); but the counter-argument is that if the implementation defined that returning NULL is possible for reasons other than allocation failure (which glibc has done), then an application aware of the implementation-defined behavior can distinguish between whether a NULL return implies that the old pointer was deallocated (in glibc's case, the documentation is that errno will be ENOMEM on allocation failure, and unchanged on the realloc(p,0) successfully freeing a pointer). It is not obvious whether the C99 wording claims to have exhaustively listed all possible return types into just two buckets, or whether it has has merely listed the two possibilities that apply only to unconditional requirements, while leaving a third possibility (namely, the return value when the implementation-defined behavior has kicked in) unwritten. Therefore, I'm not sure whether a blanket statement that glibc is non-compliant to C99 will help; can you instead word it along the lines of "There is an unsettled debate on whether glibc's behavior is a compliant use of implementation-defined behavior for a size of zero or a non-compliant case of returning NULL for more than just an allocation failure"? I don't think weakening this sentence along these lines will negatively impact the overall call for C2y to tighten behavior going forward. Rather, it is easy to defend as fact that there is (still!) a community debate (just point to this thread!) and easy enough to call out two possible interpretations; and that comes across as less argumentative than declaring as fact that glibc is either compliant or non-compliant. Choosing a side alienates people who have the opposite view, while acknowledging that there are (at least) two possible viewpoints lets people of both persuasions still feel included. (Declaring compliance becomes a lot easier if you can state that "implementation abc fails standards-conformance text xyz" - but I'm not sure anyone can point to a comprehensive industry-accepted standards-conformance test for C99 compliance; the POSIX folks _do_ have a standards conformance test suite, but then you have the problem that most vendors that have tried to pass that have not been using glibc) > > Proposed wording > Based on N3550. > > @@ p3 > If <tt>ptr</tt> is a null pointer, > the <b>realloc</b> function behaves > like the <b>malloc</b> function for the specified size. > Otherwise, > if <tt>ptr</tt> does not match a pointer > earlier returned by a memory management function, > or > if the space has been deallocated > by a call to the <b>free</b> or <b>realloc</b> function, > ## We can probably remove all of the above, because of the > ## behavior now being defined as-if by calls to malloc(3) and > ## free(3). But let's do that editorially in a separate change. > -or > -if the size is zero, > ## We're defining the behavior. > the behavior is undefined. > If > -memory for the new object is not allocated, > +the space cannot be allocated, > ## Editorial; for consistency with the wording of the other functions. > the old object is not deallocated > and its value is unchanged. > +XXX) > > @@ New footnote XXX > +XXX) > +While atypical, > +<b>realloc</b> may fail > +for a call that shrinks the block of memory. Is it worth wording this as "may fail or return a different pointer for a call that shrinks the block of memory"? -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org