Clarification Request

Document Number: N2438
Submitter: Nick Stoughton
Submission Date: 2019-08-08
Source: Austin Group
Reference Document: N2176 C17
Subject:Realloc with size 0 ambiguity

Summary

DR400 was resolved and included in C17, but the resolution still appears to contain an ambiguity with respect to realloc(ptr, 0) (although such behavior is marked as obsolete, code still exists that does this).

C17 7.22.3p1 states that

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.
In 7.22.3.5p3 there is a further statement:
If size is zero and memory for the new object is not allocated, it is implementation-defined whether the old object is deallocated. If the old object is not deallocated, its value shall be unchanged.
and in Returns (para 4):
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.

Is realloc(ptr, 0) permitted to return NULL for the non-error case where the memory at ptr has been deallocated without this being treated as an error?

Existing Practice

POSIX currently states

Upon successful completion, realloc() shall return a pointer to the (possibly moved) allocated space. If size is 0, either:
  • A null pointer shall be returned and, if ptr is not a null pointer, errno shall be set to an implementation-defined value.
  • A pointer to the allocated space shall be returned, and the memory object pointed to by ptr shall be freed. The application shall ensure that the pointer is not used to access an object.
  • If there is not enough available memory, realloc() shall return a null pointer and set errno to [ENOMEM]. If realloc() returns a null pointer and errno has been set to [ENOMEM], the memory referenced by ptr shall not be changed.

    The requirement to set errno to an implementation-defined value if realloc(ptr,0) returns a null pointer was added in 2013 (2008-TC1).

    Note that glibc returns null without setting errno in this case, and that Solaris and macOS used to do the same but in Solaris 11.4 and in macOS El Capitan and later, it does not return null. In the 2011 meeting that discussed DR400, participants from IBM and HP also indicated they would change their implementations, although this has not been verified. Glibc and GCC continue to support zero-sized objects as an extension to the C standard.

    Possible Change

    Change 7.22.3.5p3

    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.
    to
    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 to indicate a failure and that the new object has not been allocated.
    .