This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 8/6/19 2:58 PM, DJ Delorie wrote: > > for realloc(ptr, 0), I read it this way: > >> If size is zero and memory for the new object is not allocated, it is >> implementation-defined whether the old object is deallocated. > > We define it as "the old object is deallocated" > >> 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 has not been allocated. > > We return a NULL poiner as a new object is not allocated. > >> C17 7.31.12 Invoking realloc with a size argument equal to zero is an >> obsolescent feature. > > And the user shouldn't be doing this anyway. > > I don't see where the conflict is. Am I missing something? Yes: > C11 7.22.3 (overview): 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. Which, when read carefully, permits the implementation to define situations where it returns NULL on success. > C17 7.22.3.1 (overview): If the size of the space requested is zero, the > behavior is implementation-defined: either a null pointer is returned to > indicate an error, 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. Which has an added phrase: "a null pointer is returned to indicate an error"; read strictly, the implementation is NOT allowed to return NULL except on error, but glibc's realloc(ptr,0) returns NULL without setting errno. And POSIX wants to ensure that anywhere a C function returns an error, then errno is reliably set. Of course, the more specific realloc section in 7.22.3.5 does sound like an implementation can get away with returning NULL on success, but since this contradicts the overview section 7.22.3.1, it is hard to decipher the intent. And that contradiction is what is new to C17. Whether that was the intended result of WG14's Defect 400 is unclear, but we probably need WG14 to answer a new defect to clear up what IS intended, to make sure that the Austin Group does not mandate something that will be incompatible with C17 or glibc behavior, and/or whether glibc is even willing to consider having a versioned realloc which behaves differently for C17/POSIX8 than for C99/C11/POSIX7. Knowing what glibc is willing or unwilling to do may help sway whether the Austin Group can add a restriction above-and-beyond C that would require realloc(ptr,0) to either always match what malloc(0) does (if the former always returns NULL with errno of EINVAL because 0-sized objects are not supported then so must the latter; if the former returns a non-NULL object or fails with errno of ENOMEM, but never returns NULL without touching errno, then so must the latter) or to always fail with errno of EINVAL (because C17 said realloc with size 0 is obsolescent, and making it always fail is an easy way to get code to quit relying on whatever random semantics it used to have in older setups), but adding either of those restrictions would mean that realloc(ptr,0) can no longer be glibc's current synonym for free(ptr) without a matching malloc attempt. There are other places where POSIX already places restrictions above-and-beyond C, such as requiring errno to be reliably set anywhere that the C standard requires a function to fail; or requiring the NULL macro to expand to something with explicit void* type as in '#define NULL ((void*)0)' rather than the looser C rule which permits '#define NULL 0'; or requiring function pointers to be convertable to void* and back without loss of information for the sake of dlsym(), or requiring 'char' to be exactly 8 bits, etc. But while documenting which errno values realloc will set is a place where POSIX already restricts beyond what C says, the question of whether placing new restrictions on realloc(x, 0) is appropriate is still up for debate. My personal take is that the Austin Group should permit existing glibc behavior insofar as glibc behavior doesn't violate C17. Placing a restriction beyond C that would require a versioned realloc in glibc is not a good idea unless glibc developers first agree to be willing to go that route - so arguments describing pros and cons of glibc even considering a versioned realloc are helpful. Florian has already given one argument against a versioned realloc based on the frequency of malloc interposition - given that there are already a number of libraries that replace malloc with their own implementation (whether for performance reasons such as jemalloc, tcmalloc; or for debug reasons such as valgrind), because having to replace two different versions of realloc across multiple implementations just makes life even more complicated. But it's a tough call when I can't decipher whether C17 is self-consistent, and therefore can't state whether glibc is compliant as-is. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |