Philipp Klaus Krause schreef op 2025-09-08 13:32:
Am 06.09.25 um 21:44 schrieb Alan Cox:

I would disagree with your interpretation re C90. It's possible to
allocate zero bytes, it's just metadata tracking space that is allocated but it's not an impossible act. So I believe you are compliant with C90
anyway. They just made it more explicit.

Classic Unix returned a pointer for zero sized allocations and realloc.

Well, the C90 wording is somewhat unclear:

#include <stdlib.h>
void *realloc(void *ptr, size-t size);
Description
The realloc function changes the size of the object pointed to by ptr
to the size specified by size. The contents of the object shall be
unchanged up to the lesser of the new and old sizes. If the new size
is larger, the value of the newly allocated portion of the object is
indeterminate. If ptr is a null pointer, the realloc function behaves
like the malloc function for the specified size. Otherwise, if ptr
does not match a pointer earlier returned by the calloc, malloc, or
realloc function, or if the space has been deallocated by a call to
the free or realloc function. the behavior is undefined. If the space
cannot be allocated, the object pointed to by ptr is unchanged.

If size is zero and ptr is not a null pointer, the object it points
to is freed.

IMHO this clearly states that the effect of calling realloc(ptr, 0)
should be the same as calling free(ptr). Afterwards it is illegal to
dereference a copy of this pointer.
What it doesn´t say is if it may allocate some new memory whose
pointer is returned and should be freed later to prevent a memory
leak.

Returns
The realloc function returns either a null pointer or a pointer to
the possibly moved allocated space.

My understanding was that this would require realloc(ptr, 0) to free
and return a null pointer. AFAIK, that was also the understanding
glibc came up with.
From the C99 rationale, this was apparently an obvious, but not
necessarily desired understanding: "C89 appeared to require a null
return value, and the Committee felt that this was too restrictive."

There is also this statement in the C90 standard:

If the space cannot be allocated, a null pointer is returned.
If the size of the space requested is zero, the behavior is
implementation-defined; the value returned shall be either a null
pointer or a unique pointer.

So for C90 it is allowed to return a null pointer for size==0, but not
required.

If a null pointer is returned it need not mean that the requested
size could not be allocated. Only the reverse is specified. And thus
it is also not required that the object pointed to is left unchanged.
Even stronger: it is required to be freed.

If a non-null pointer is returned it should be unique.

It should allowed to pass the returned pointer to realloc() or free().

So, we can choose to free(ptr) and return a null pointer, or we can
choose to free(ptr) and allocate metadata for an object of 0 bytes
and return that pointer. Since in our implementation the metadata is
allocated in the same heap space as the object the pointer is
automatically unique.

I'll probably change the manual to state that C90 is unclear here, and
sdcc might or might not conform.

Philipp

Maarten


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to