CBFalconer said:
You have specified that request_malloc is shorthand for a sequence
involving malloc and sizeof_alloc. The response cannot be
different, and should not, because such differences create major
confusion.
You are right that the proposal summarizes:
This call is intended to encapsulate a call to malloc and a call to
sizeof_alloc into a single function.
Then the postcondition goes on to state exactly what request_malloc
does, and it may be different for the 0 requested size case (depending
upon how malloc is implemented).
Thank you for pointing out this contradiction. If I get a chance to
rewrite this proposal, I will try to correct that.
The only difference I wish to see between malloc and request_malloc for
zero-sized requests is portable behavior. The behavior of malloc(0)
isn't portable and I wish for the behavior of request_malloc(0,0) to be
portable. That should've been made clear in the proposal.
One system that I created changes all 0 size requests to 1.
You
can see the system on my pages, download section, nmalloc.zip.
Thank you for the link.
The
reason is that once the allocation is freed it has to go into the
appropriate free list, and needs further links. The actual (now
unused) allocation space (rounded up) can supply this, for a
non-zero size.
Yet even though your malloc(0) always returns non-null, free(0) must
still respond appropriately (as yours does modulo an optional? warning).
From 7.20.3.2p2:
If ptr is a null pointer, no action occurs.
Lying back to the user about the actual size defeats the whole
purpose of the arrangement, which is to allow expansion without
system calls.
I have no desire for the proposed interface to lie to the client. I
wish for the interface to be portable. malloc(0) is not. It may return
0, or it may not. From 7.20.3p1:
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.
I have implemented both interfaces on several platforms, both hosted and
freestanding (though malloc is an extension on freestanding platforms).
I have had no difficulty in offering both interfaces on all platforms,
save backward compatibility issues.
In nmalloc, if you request 0 you will actually get
at least ALIGN bytes (which happens to be 8), possibly more if a
residue is too small to be of use in forming another allocation.
So malloc(0) will normally return non-NULL, and as many as 32 bytes
may be available in my system. For that package at least 8 bytes
will be available.
<nod> I see no reason that you could not layer request_malloc, as
proposed, on nmalloc. It simply would check for the 0 case and return 0
before calling nmalloc. Alternatively, if nmalloc were to be rewritten
and layered on request_malloc, it would do as it does now: check for 0
and change it to 1 if found.
I'm clearly not understanding your concern, and I would like to. Sorry
if I'm just being dense.
What would be your preference:
1. request_malloc(0,0) return 0
2. request_malloc(0,0) return nonzero
3. request_malloc(0,0) return 0 or nonzero, implementation defined
?
I'm arguing for 1 or 2, with a slight preference for 1. But I would
really like to avoid 3. I believe it would make portable programs
harder to write, with no real advantage coming from that cost.
I prefer 1 because it requires less heap to implement it. And I am
sensitive to resource constrained (embedded) environments.
-Howard