Does realloc(p, 0) do the equivalent of malloc(0) and then frees p if successful? Does it simply free p? Is it undefined? Who even knows anymore, because they changed it too many times (literally at least 3 times) and while I think it's undefined now it's very commonly used...
Conversation
I'm somewhat responsible for this being UB, so I feel compelled to defend it (my preferred outcome was "implementation-defined", not that that's much better). In our defense: the reality on the ground was that you can't write a portable program that does realloc(p, 0) and (1/3)
1
2
gets a sane result, regardless of what the standard says or could have said. So the committee chose to acknowledge that fact. Making this "anything goes" lets each implementation maintain its current behavior, and also allows new ones (e.g. the next jemalloc release will (2/3)
1
1
allow free/malloc(0)/abort semantics, set per-process). The switch from free to malloc(0) was out of a desire to mitigate the security footgun of the free semantics, I believe (though that was before my time). (3/3)
1
1
BTW. What worries me more about jemalloc is that with MADV_FREE on Linux allocated memory is not stable. It is sometimes claimed (but IMHO not true) that this is allowed by the standard.
1
> The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
> indeterminate value
> either an unspecified value or a trap representation
2
trap representation does not imply when looking at the memory as bytes (character types). And unspecified values should be stable.
1
LLVM was happily treating every uninitialized variable the same way such as happily reading the results of some register not reserved for it with arbitrary contents that may change. That's what undef does. That stuff is changing for unrelated reasons though.
1
1
LLVM does a lot of crazy stuff and even inconsistenly, so had quite a few optimization bugs. This seems to get cleared up gradually but whether this is then standard compliant or not is another question (or what we should do on the standards side is under discussion).
2
If it's not undefined behavior, then it's not standards compliant to compile C programs which error out if they read uninitialized memory. One possible thing UB allows you to do is detect the error and abort. I think most implementations have been treating it as just being UB.
When the wording is so unclear and vague, that's just how things work out. It's often not clear what the C standard really expects in these cases.
Another good example is how are implementations supposed to handle stack exhaustion when the standard ignores the issue entirely?
2
1
I think the only valid way to deal with that would be having that entire thread stall indefinitely since no one said anything about how fast progress had to be made.
Overflowing in a completely unsafe way doesn't seem compliant, and safely detecting + aborting doesn't either.
1
Show replies


