Reputation: 214770
According to the change log of C23, proposal n2464 was voted-in and implemented, making realloc(ptr, 0)
explicitly undefined behavior, whereas it was supposedly implementation-defined in previous standards. In the drafts (quotes are from n3096), the specification of realloc
has been changed accordingly: (bold emphasis mine)
7.24.3.7 The realloc function
/--/
...or if thesize
is zero, the behavior is undefined
However, in the C23 drafts we can also read:
7.24.3 Memory management functions
/--/
If the size of the space requested is zero, the behavior is implementation-defined
Annex J.1 Unspecified behavior
(46) The amount of storage allocated by a successful call to the calloc, malloc, realloc, or aligned_alloc function when 0 bytes was requested (7.24.3).
Annex J.2 Undefined behavior
(179) A non-null pointer returned by a call to the calloc, malloc, realloc, or aligned_alloc function with a zero requested size is used to access an object (7.24.3).
Annex J.3.12 Implementation-defined behavior
(42) Whether the calloc, malloc, realloc, and aligned_alloc functions return a null pointer or a pointer to an allocated object when the size requested is zero (7.24.3).
Now, I did try to point out this defect to the ISO C WG through informal channels, but to deaf ears evidently, since the defects are still there in draft n3220. 7.24.3.7 and 7.24.3 are both normative texts, whereas Annex J is informative (and already filled to the brim with errors even before C23, never to be trusted). So which of the contradicting texts is "most normative"?
May old programs with realloc(ptr, 0)
get ported to C23 and the same implementation-defined behavior might still be there? Or will such code be non-portable to C23 since it invokes UB? Or will this remain a defect after publication and we have to wait for a TC to get published?
Upvotes: 32
Views: 884
Reputation: 14493
On a more practical aspect - for most of us, the question is what's the behavior of GNU LIBC and MUSL. I believe in both case, those library have practically "committed" to specific behavior many years ago (specifically, realloc(ptr, 0) same as free(ptr)). They are unlikely to make a non-backward compatible changes.
I do not have current access to other vendors (e.g., Oracle, IBM) - as much as I remember most have all practically aligned to above behavior.
Bottom line - my opinion (not legally binding) - Unless your code has to meet very strict "standard compliance" rules - there is no practical impact on the C23 note
There is good discussion https://www.reddit.com/r/C_Programming/comments/128vjag/comment/jel2wbb/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button)
Upvotes: -1
Reputation: 31409
I'm not 100% sure, but a quite reasonable analogy comes from law. In law, there is a doctrine called "lex specialis" which means that specific rules takes precedence over general ones, under the assumption that those who wrote one of them was aware of the other.
Following this principle, the behaviour should be undefined, since a rule that specifically addresses the realloc
function is more specific than "memory management functions"
Upvotes: 0