Hacker News new | ask | show | jobs
by kazinator 887 days ago
> C99 does not guarantee you can use realloc() in this manner

Yes it does. It requires support for reallocing down to zero, which results in an object that is like one that comes from malloc(0).

(What some people think is that realloc(x, 0) is equivalent to free(x). It isn't. Resizing down to zero isn't freeing. It might be, if malloc(0) doesn't allocate anything and just returns null. Why some people think realloc(x, 0) is free(x) is that they read realloc man page from the Linux man-pages project which says such a thing.)

realloc(ptr, 0) could fail to free ptr, in the situation that allocating the zero-sized replacement object fails. In that case, null could be returned, leaving the old object valid. This is ambiguous, because null could also be the happy case return value when the old object was freed and the zero-sized allocation deliberately produced null. Under those conditions, the cases in which there is a memory leak are indistinguishable from the ones in which there isn't.

(I'd rather suffer a memory leak in the OOM condition, than have previously defined behavior gratuitously flip to undefined.)

1 comments

I literally quoted someone from WG14.

HN really needs the ability to block trolls.

You quoted someone who stated they are not happy with C23, and deflected personal blame for that issue.

If I'm only trolling, then why, having learned about this, am I having to go into code and make defensive fixes?

They aren't defensive foxes. They're just fixes. Any C99+ code that relied on your assumed realloc(p, 0) behavior was always incorrect.
Yes, a fix inside a realloc wrapper is a defensive fix, if nothing is actually calling with the zero size in the current code base, and/or we are not yet compiling with C dialect selection that corresponds to the vandalized standard. It's an example of defensive programming, coding intended to anticipate and thwart a future problem.

Code that calls realloc(p, 0) and does not assume any one of the behaviors that are described is not incorrect according to C99.

That's par for the course in C. In C, there are situations left and right in which you're stepping on implementation defined behavior and mustn't assume a particular one.

A lot of portable coding is defensive. It can end up more portable than required. That is to say, if we consider all the platforms but the program actually ends up used over its lifetime, we can deduce that a less portable approach in some part of the code would have worked just fine.