Honestly kind of irrelevant
Honestly kind of irrelevant
Posted Oct 29, 2024 8:38 UTC (Tue) by chris_se (subscriber, #99706)Parent article: realloc() and the oversize importance of zero-size objects
Even if the code is used in non-portable programs that are designed for just a single operating system, I still don't like them. There are some implementation-defined behaviors (such as relying on two's complement or 8bit byte sizes) where it can make a lot of sense to rely on those, because not assuming that would make the code a **lot** more complicated for no benefit at all in many cases. (And platforms that that don't use e.g. two's complement are extremely rare nowadays.) But avoiding malloc(0) or realloc(ptr, 0) is just 1-2 more lines of code. And if it's handled explicitly it is 100% clear what the code intends to do. In the absence of explicit handling that's not the case, and then one doesn't immediately know whether the code actually relies on that behavior, or whether there's a bug in there and the author didn't even think about that corner case.
I personally would leave the current behavior as-is, because I don't see any benefit of changing it, because in my opinion nobody should ever write new code that relies on these kinds of specifics. But I also don't really care if they do decide to change that behavior.
Posted Oct 29, 2024 10:10 UTC (Tue)
by Wol (subscriber, #4433)
[Link] (1 responses)
I know this sort-of goes against the grain of being a standard, but why not say "here are two competing versions, you have to provide both (with a compiler switch), but we take no position on the default".
Khim's point about ISO saying Posix can do what it likes, when Posix explicitly defers to ISO, does imho appear daft. And if you want ISO C to be portable, specifying the two dominant (Posix and MS) implementations and saying "support both" seems to be the right way to go ... whether others agree is another matter ...
Cheers,
Posted Oct 31, 2024 18:10 UTC (Thu)
by NYKevin (subscriber, #129325)
[Link]
#define malloc_s(size) (size == 0? (void*)NULL : malloc(size))
And then the compiler can optimize that back into a malloc/realloc call easily enough, if it knows that malloc/realloc have the appropriate semantics on a given platform.
Getting unique non-dereferencable pointers is harder, and IMHO should not be done, because (as I've explained elsewhere in the thread) it is cheaper to have a global u64 and atomically increment it (malloc takes a lock in almost any sensible implementation). If you somehow manage to allocate over 16 quintillion numbers in this fashion (so that it wraps), then you probably should be using UUIDs instead of 64-bit integers in the first place.
Honestly kind of irrelevant
Wol
Honestly kind of irrelevant
#define realloc_s(ptr, size) (size == 0 ? free(ptr), (void*)NULL : realloc(ptr, size))