Hi Rich,

On Fri, Jun 20, 2025 at 10:42:58PM -0400, Rich Felker wrote:
> On Fri, Jun 20, 2025 at 06:34:25PM -0700, Paul Eggert wrote:
> > On 2025-06-20 18:06, Alejandro Colomar wrote:
> > >   +       to both return a null pointer and set errno to ENOMEM.
> > 
> > Given the proposed change, I don't see why ENOMEM must be added to the C
> > spec. The spec changes malloc and realloc so that returning null means
> > failure (i.e., out of memory) and returning non-null means success. In that
> > case, there seems to be no pressing need for ENOMEM in the C standard (as
> > opposed to POSIX).
> > 
> > If ENOMEM is really needed, its presence should be justified in the
> > proposal. Alternatively, the proposal could be divided into two: the main
> > proposal is the null-if-and-only-if-failure part, and ENOMEM could be the
> > secondary proposal.
> > 
> > One other thing: Doug McIlroy's point was that realloc(p,n) should never
> > fail when p already addresses storage of size n or greater. As a corollary,
> > realloc(p,0) should never fail when p is non-null. It might be helpful to
> > add this as a third proposal. A lot of apps already assume McIlroy's point,
> > after all.
> 
> I'm very much opposed to such a change. Many (I would say most good)
> allocator designs do not admit resizing down in-place due to
> segregating allocations by size in slab-like strategies where the size
> of the object may even be implicit in its address. While it's possible
> to make them simply decline to resize-down, leaving the original
> full-sized allocation, this has multiple very negative properties:
> 
> 1. It exacerbates OOM conditions by preventing the application from
>    knowing about them and being able to react. If the application
>    thinks N operations of resizing allocations each of some large size
>    M down to some small size K succeeded, it has tied up N*(M-k) bytes
>    more than it expected, and it does not know it can free these
>    objects to reclaim this memory.
> 
> 2. It undermines hardening. Our malloc implementation guarantees
>    catching even single-nonzero-byte buffer overflows past the nominal
>    allocation size. This requires having the ability to represent the
>    exact size. Because the difference between the slot size and
>    nominal allocation size is bounded and small, the representation of
>    the difference can be stored very compactly. This cannot be done as
>    efficiently or in the same manner if the difference can be
>    arbitrarily large.
> 
> 3. It breaks the common extension function malloc_usable_size. As in
>    (2) above, we have malloc_usable_size return the exact nominal
>    size. This is necessary to prevent inconsistencies where the
>    compiler optimizes with knowledge that the object size is at most
>    N1 but malloc_usable_size returns a larger value N2, breaking
>    catastrophically. (Admittedly having malloc_usable_size to begin
>    with was the mistake here, but that ship has sailed.)

Interesting.  Thanks!

> 
> Applications have always needed to be prepared for the possibility
> that realloc can always fail, including when reducing the size. Unless
> I'm mistaken, this happens even on dlmalloc-like allocators when the
> old size is above the "mmap threshold" and the new size is below. A
> good allocator is not going to leave an object that was originally
> allocated at a large 256k buffer using at least a whole page when it's
> resized to 16 bytes.
> 
> As this proposal is completely unrelated to fixing the UB and
> inconsistency of realloc(p,0) on some implementations, and it's a
> breaking change as described above, I would like to see it dropped
> from the agenda.

Yep, it was never part of this proposal of mine.

I'll drop the quote, as I had understood it from another point of view.
This will avoid confusion.


Have a lovely day!
Alex

> 
> Rich

-- 
<https://www.alejandro-colomar.es/>

Attachment: signature.asc
Description: PGP signature

Reply via email to