Hi,

On 02/21/2013 04:01 PM, Marc Lehmann wrote:
The C89 standard says (any typos are mine):

    7.10.3.4 the realloc function

    [...]

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

Your quote is from 7.10.3, and only applies if an allocation is actually
requested ("If the size of the space requested..."), which isn't the case
for the case above.

taking 7.10.3.4 into account, yes, I agree.

If you want to argue that the ISO-C requirement "the object it points to
is freed" does not mean free(ptr) or an equivalent is called then we will
have to disagree.

I agree it means free(ptr). I wasn't aware of the wording change. Thanks for the heads-up.

So, in essence, this means the current glibc realloc() violates the C89 standard but is C99-conformant? I like the C89 behaviour – it enables one to wrap all allocation business neatly into one single function. Yet, the defect report you pointed out appears to undermine this usage even further.

As for libev, for the benefit of its users, I suggest to explain the expected behaviour of the allocator function explicitly in the documentation, to avoid confusion due to more recent standards steering more and more away from the C89 realloc() specification. I have attached a patch for ev.pod to that effect.

Best regards,
Alexander
--- ev.pod.old	2013-02-22 16:10:28.937296060 +0100
+++ ev.pod	2013-02-22 16:46:31.977351443 +0100
@@ -251,15 +251,29 @@
 
 =item ev_set_allocator (void *(*cb)(void *ptr, long size) throw ())
 
-Sets the allocation function to use (the prototype is similar - the
-semantics are identical to the C<realloc> C89/SuS/POSIX function). It is
-used to allocate and free memory (no surprises here). If it returns zero
+Sets the allocation function to use. It is used to allocate and free memory
+(no surprises here).
+
+If called with a null pointer and a positive size as arguments, its semantics
+are identical to calling C<malloc> with the size as argument.
+
+If called with a pointer returned previously and a positive size as
+arguments, its semantics are identical to calling C<realloc>.
+
+If called with a pointer returned previously and a size of zero as arguments,
+its semantics are identical to calling C<free> with the pointer as argument.
+
+If called with a null pointer and a size of zero as arguments, the allocation
+function should return a null pointer and perform no other action.
+
+The allocation function will never be called with other arguments than
+described above. If it returns a null pointer
 when memory needs to be allocated (C<size != 0>), the library might abort
 or take some potentially destructive action.
 
-Since some systems (at least OpenBSD and Darwin) fail to implement
-correct C<realloc> semantics, libev will use a wrapper around the system
-C<realloc> and C<free> functions by default.
+Since some systems (at least OpenBSD, Darwin and newer versions of glibc)
+fail to implement correct C89 C<realloc> semantics, libev will use a wrapper
+around the system C<realloc> and C<free> functions by default.
 
 You could override this function in high-availability programs to, say,
 free some memory if it cannot allocate memory, to use a special allocator,
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to