On 2025-06-20 13:58:23 +0200, Alejandro Colomar wrote:
> On Fri, Jun 20, 2025 at 04:11:23AM +0200, Vincent Lefevre wrote:
> > You should also consider the end of 7.20.3p1 (which applies to calloc,
> > malloc and realloc):
> > 
> >   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.
> 
> Right.  I missed that part.
> 
> So, C99 and C11 allow realloc(p,0) to return a null pointer.
> 
> > Consider the case "a null pointer is returned" with realloc(non_null,0).
> > I can see 2 possible interpretations:
> > 
> > 1. This is always a failure (corresponding to "a null pointer if the
> > new object could not be allocated" in 7.20.3.4p4). But I doubt that
> > this is the intended behavior, as there would be major memory leaks
> > in practice with such an implementation and would make such a call
> > useless.
> > 
> > 2. This means that the memory is entirely freed, which is a success.
> > This makes your assumption "paragraph 4 rules out the possibility of
> > returning a null pointer on success" above wrong. However, in order
> > to know whether a null pointer means a success (memory entirely freed)
> > or a failure (for the case "the behavior is as if the size were some
> > nonzero value"), the application would need to know which kind of
> > implementation it is (e.g. guessed by tools like configure tests).
> 
> To disambiguate, we need to read
> 
> <https://port70.net/~nsz/c/c99/n1256.html#7.20.3.4>
> 
> First p4:
> 
>       4       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, a null pointer, which is allowed for r(p,0), means that "the new
> object could not be allocated".
> 
> And then we read the last sentence of p3:
> 
>       3       [...]
>               If memory for the new object cannot be allocated,
>               the old object is not deallocated and its value is unchanged.
> 
> So, the input pointer must not be freed.

Yes, this is what I mentioned in interpretation 1 above (so with
memory leaks in practice, as applications call realloc(non_null,0)
to free memory, while memory will never be freed).

But I believe that this was not the intent of the C Committee.
If it were, the text would have been different, IMHO.

This is too late for a defect report anyway, as the current standard
is C23 and realloc(non_null,0) is now UB. But if one wants to avoid
the UB in a future standard, the above remarks need to be considered.

> I'd say glibc is non-conforming, even if this could possibly have been
> unintended by the C Committee.

Well, strictly speaking, with the UB, it is conforming (at least with
a non-null pointer). I'm not sure that speaking of conformity against
old standards makes sense if there is a suspicion of defect (and in
particular, if this has been resolved by a change in the current
standard, like here).

-- 
Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)

Reply via email to