digitalmars.D - std.allocator.allocate(0) -> return null or std.allocator.allocate(1)?
- Andrei Alexandrescu (29/29) May 15 2015 This is a matter with some history behind it. In C, malloc(0) always
- Andrei Alexandrescu (3/4) May 15 2015 To clarify: I want to request all allocators to return null if asked for...
- Vladimir Panteleev (7/38) May 15 2015 There is a third option: return a non-null yet invalid pointer
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (4/34) May 15 2015 Not necessarily a good idea, but there's a third option:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (2/47) May 15 2015 Ha! Two fools, one thought :-)
- Andrei Alexandrescu (9/10) May 15 2015 It's a nice idea but as Vladimir mentioned expand(), reallocate(),
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (4/14) May 15 2015 Yes, and std.allocator is a new piece of software, which means we
- Vladimir Panteleev (5/7) May 15 2015 Question, is there a strong rationale for this? The usefulness is
- Andrei Alexandrescu (4/10) May 15 2015 Yah, you don't want to special case null everywhere: cleanup functions,
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/13) May 15 2015 You should, C is just not a language designed for type safety and
- deadalnix (7/13) May 15 2015 There are actually 2 way to do this in malloc. Either you return
- Andrei Alexandrescu (5/19) May 15 2015 Ah, nice. I was under the misconception that malloc(0) cannot return
- Andrei Alexandrescu (5/25) May 15 2015 Well I added the rule that allocate(0) should return null, there are a
- deadalnix (8/12) May 15 2015 I do think think this is what makes sense for us:
- Timon Gehr (3/12) May 15 2015 - Too much overhead, there might be a fall-back installed.
- Andrei Alexandrescu (3/17) May 15 2015 Yeh, failed allocations are relatively frequent within the framework
- Walter Bright (2/3) May 16 2015 I find this surprising.
- Andrei Alexandrescu (11/15) May 16 2015 Consider a fixed-length buffer fronting a general allocator, one of the
- Walter Bright (3/16) May 16 2015 Ah, ok, that makes sense. I was thinking more in terms of the whole prog...
- Andrei Alexandrescu (7/17) May 16 2015 One more illustration of the same idea: just completed a larger doc.
- Jacob Carlborg (4/5) May 16 2015 Per-allocated? The same way as out of memory is handled in the runtime.
- Andrei Alexandrescu (4/7) May 16 2015 Regardless, std.allocator does not use exceptions anywhere (it is,
- Jacob Carlborg (4/5) May 16 2015 To avoid confusion, that should have been "pre-allocated".
- deadalnix (3/7) May 16 2015 if (fallbackInstalled) return fallbackAllocate();
- Timon Gehr (3/30) May 15 2015 - Quantizer currently does not necessarily follow this rule.
- Idan Arye (2/33) May 17 2015 How about defining `alloc.allocate(0)` to *be* an error?
- Timon Gehr (2/4) May 17 2015 What is bad about allocate(0)?
- Idan Arye (7/12) May 17 2015 It's not that allocating 0 bytes is wrong by itself(at first
- Andrei Alexandrescu (16/28) May 17 2015 Prolly not a good idea, 0 works well for the most part as a natural
- Peter Alexander (3/6) May 17 2015 Is the invariant malloc(0) != malloc(0) the only thing that makes
- Andrei Alexandrescu (5/11) May 17 2015 I thought so, but apparently C99 _does_ allow malloc(0) to return null,
- deadalnix (2/9) May 17 2015 Doesn't need to be, the spec only say it must be passable to free.
- Peter Alexander (3/14) May 18 2015 So here's my question: can we just make allocate(0) do nothing
- Andrei Alexandrescu (3/16) May 18 2015 Yes, allocation could be rounded to whatever minimum the allocator
This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there. The reasoning was to make failure of malloc easy to test for. This would suffice: size_t s; ... void* p = malloc(s); if (!p) { ... failed! ... } as opposed to: if (!p && s) { ... failed! ... } That kinda makes sense, but it's not super consistent. For example, realloc() does not obey the same protocol. Calling realloc() with a new size of 0 actually free()s the pointer and then returns null. Anyhow, on to D. In D it's easy to test whether an allocation succeeded: auto buf = alloc.allocate(s); if (buf.length != s) { ... failed! ... } It is a bit subtle, but I think overall it makes everyone's life easier. Thoughts? Andrei
May 15 2015
On 5/15/15 9:36 AM, Andrei Alexandrescu wrote:Anyhow, on to D.To clarify: I want to request all allocators to return null if asked for zero bytes. -- Andrei
May 15 2015
On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there. The reasoning was to make failure of malloc easy to test for. This would suffice: size_t s; ... void* p = malloc(s); if (!p) { ... failed! ... } as opposed to: if (!p && s) { ... failed! ... } That kinda makes sense, but it's not super consistent. For example, realloc() does not obey the same protocol. Calling realloc() with a new size of 0 actually free()s the pointer and then returns null. Anyhow, on to D. In D it's easy to test whether an allocation succeeded: auto buf = alloc.allocate(s); if (buf.length != s) { ... failed! ... } It is a bit subtle, but I think overall it makes everyone's life easier. Thoughts? AndreiThere is a third option: return a non-null yet invalid pointer (e.g. 0x1) that is used exclusively for empty allocations. This allows the if(p) pattern and elides the cost of allocating one byte, however it complicates allocator code a bit (resizing, freeing needs to know about this magic pointer), and breaks the contract malloc(size)!=malloc(size).
May 15 2015
On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there. The reasoning was to make failure of malloc easy to test for. This would suffice: size_t s; ... void* p = malloc(s); if (!p) { ... failed! ... } as opposed to: if (!p && s) { ... failed! ... } That kinda makes sense, but it's not super consistent. For example, realloc() does not obey the same protocol. Calling realloc() with a new size of 0 actually free()s the pointer and then returns null. Anyhow, on to D. In D it's easy to test whether an allocation succeeded: auto buf = alloc.allocate(s); if (buf.length != s) { ... failed! ... } It is a bit subtle, but I think overall it makes everyone's life easier. Thoughts?Not necessarily a good idea, but there's a third option: return cast(void*) -1; Or some other arbitrary non-zero value.
May 15 2015
On Friday, 15 May 2015 at 16:43:35 UTC, Marc Schütz wrote:On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Ha! Two fools, one thought :-)This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there. The reasoning was to make failure of malloc easy to test for. This would suffice: size_t s; ... void* p = malloc(s); if (!p) { ... failed! ... } as opposed to: if (!p && s) { ... failed! ... } That kinda makes sense, but it's not super consistent. For example, realloc() does not obey the same protocol. Calling realloc() with a new size of 0 actually free()s the pointer and then returns null. Anyhow, on to D. In D it's easy to test whether an allocation succeeded: auto buf = alloc.allocate(s); if (buf.length != s) { ... failed! ... } It is a bit subtle, but I think overall it makes everyone's life easier. Thoughts?Not necessarily a good idea, but there's a third option: return cast(void*) -1; Or some other arbitrary non-zero value.
May 15 2015
On 5/15/15 9:44 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:Ha! Two fools, one thought :-)It's a nice idea but as Vladimir mentioned expand(), reallocate(), free() - all need now to worry about checking two singular values instead of one. Since there's a long-established tradition that reallocate() and free() accept a null pointer, we can't (and probably shouldn't) change that. So I'm thinking in a way null as a singular value comes for "free". Andrei
May 15 2015
On Friday, 15 May 2015 at 17:01:26 UTC, Andrei Alexandrescu wrote:On 5/15/15 9:44 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:Yes, and std.allocator is a new piece of software, which means we can choose what makes sense and don't need to worry about compatibility. It just needs to be clearly defined.Ha! Two fools, one thought :-)It's a nice idea but as Vladimir mentioned expand(), reallocate(), free() - all need now to worry about checking two singular values instead of one. Since there's a long-established tradition that reallocate() and free() accept a null pointer, we can't (and probably shouldn't) change that. So I'm thinking in a way null as a singular value comes for "free".
May 15 2015
On Friday, 15 May 2015 at 17:01:26 UTC, Andrei Alexandrescu wrote:Since there's a long-established tradition that reallocate() and free() accept a null pointer,Question, is there a strong rationale for this? The usefulness is obvious if malloc(0) returns null, but otherwise, attempting to free a resource that has never been created usually indicates a bug.
May 15 2015
On 5/15/15 6:56 PM, Vladimir Panteleev wrote:On Friday, 15 May 2015 at 17:01:26 UTC, Andrei Alexandrescu wrote:Yah, you don't want to special case null everywhere: cleanup functions, destructors, etc. etc. If deallocation wouldn't accept the null pointer, "if (p) free(p);" would cause carpal tunnel syndrome. -- AndreiSince there's a long-established tradition that reallocate() and free() accept a null pointer,Question, is there a strong rationale for this? The usefulness is obvious if malloc(0) returns null, but otherwise, attempting to free a resource that has never been created usually indicates a bug.
May 15 2015
On Saturday, 16 May 2015 at 02:05:22 UTC, Andrei Alexandrescu wrote:You should, C is just not a language designed for type safety and correctness.Question, is there a strong rationale for this? The usefulness is obvious if malloc(0) returns null, but otherwise, attempting to free a resource that has never been created usually indicates a bug.Yah, you don't want to special case null everywhere: cleanup functions, destructors, etc. etc. If deallocation wouldn't accept the null pointer, "if (p) free(p);" would cause carpal tunnel syndrome. -- Andrei
May 15 2015
On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there.There are actually 2 way to do this in malloc. Either you return null, but then you need to be able to accept null in the free implementation (as malloc must return a freeable pointer) or you just bump to 1. Both are valid per spec and there are implementations of malloc for both.
May 15 2015
On 5/15/15 11:37 AM, deadalnix wrote:On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Ah, nice. I was under the misconception that malloc(0) cannot return null in C. Apparently it's implementation defined at least since C99, see http://stackoverflow.com/a/2132318/348571. Thanks! AndreiThis is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there.There are actually 2 way to do this in malloc. Either you return null, but then you need to be able to accept null in the free implementation (as malloc must return a freeable pointer) or you just bump to 1. Both are valid per spec and there are implementations of malloc for both.
May 15 2015
On 5/15/15 11:51 AM, Andrei Alexandrescu wrote:On 5/15/15 11:37 AM, deadalnix wrote:Well I added the rule that allocate(0) should return null, there are a few more tests but probably nothing worrisome: https://github.com/andralex/phobos/commit/f73f6ecf1b45b0fc3cffd50d375eb15eb2311220 AndreiOn Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Ah, nice. I was under the misconception that malloc(0) cannot return null in C. Apparently it's implementation defined at least since C99, see http://stackoverflow.com/a/2132318/348571. Thanks!This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there.There are actually 2 way to do this in malloc. Either you return null, but then you need to be able to accept null in the free implementation (as malloc must return a freeable pointer) or you just bump to 1. Both are valid per spec and there are implementations of malloc for both.
May 15 2015
On Friday, 15 May 2015 at 19:49:27 UTC, Andrei Alexandrescu wrote:Well I added the rule that allocate(0) should return null, there are a few more tests but probably nothing worrisome: https://github.com/andralex/phobos/commit/f73f6ecf1b45b0fc3cffd50d375eb15eb2311220 AndreiI do think think this is what makes sense for us: - We should throw in case of error, not return null. - There is no point in allocating something if 0 byte are going to be used. The thing we got to make sure is very clear in the spec is that free, realloc and so on functions are able to accept null as input.
May 15 2015
On 05/15/2015 10:13 PM, deadalnix wrote:On Friday, 15 May 2015 at 19:49:27 UTC, Andrei Alexandrescu wrote:- Too much overhead, there might be a fall-back installed. - Where do you allocate the exception object?Well I added the rule that allocate(0) should return null, there are a few more tests but probably nothing worrisome: https://github.com/andralex/phobos/commit/f73f6ecf1b45b0fc3cffd50d375eb15eb2311220 AndreiI do think think this is what makes sense for us: - We should throw in case of error, not return null.
May 15 2015
On 5/15/15 1:34 PM, Timon Gehr wrote:On 05/15/2015 10:13 PM, deadalnix wrote:Yeh, failed allocations are relatively frequent within the framework components. -- AndreiOn Friday, 15 May 2015 at 19:49:27 UTC, Andrei Alexandrescu wrote:- Too much overhead, there might be a fall-back installed. - Where do you allocate the exception object?Well I added the rule that allocate(0) should return null, there are a few more tests but probably nothing worrisome: https://github.com/andralex/phobos/commit/f73f6ecf1b45b0fc3cffd50d375eb15eb2311220 AndreiI do think think this is what makes sense for us: - We should throw in case of error, not return null.
May 15 2015
On 5/15/2015 6:38 PM, Andrei Alexandrescu wrote:Yeh, failed allocations are relatively frequent within the framework components.I find this surprising.
May 16 2015
On 5/16/15 2:07 AM, Walter Bright wrote:On 5/15/2015 6:38 PM, Andrei Alexandrescu wrote:Consider a fixed-length buffer fronting a general allocator, one of the simplest and most useful compositions of allocators, which I call FallbackAllocator: https://github.com/andralex/phobos/blob/allocator/std/experimental/allocator/fallback_allocator.d Once the memory in the front buffer is exhausted, the fallback allocator starts getting used. The correct way to handle the choice in the composer is to first try the front, and if it returns null, defer to the fallback. Many other allocators follow similar patterns. AndreiYeh, failed allocations are relatively frequent within the framework components.I find this surprising.
May 16 2015
On 5/16/2015 9:34 AM, Andrei Alexandrescu wrote:On 5/16/15 2:07 AM, Walter Bright wrote:Ah, ok, that makes sense. I was thinking more in terms of the whole program running out of memory, not fallback.On 5/15/2015 6:38 PM, Andrei Alexandrescu wrote:Consider a fixed-length buffer fronting a general allocator, one of the simplest and most useful compositions of allocators, which I call FallbackAllocator: https://github.com/andralex/phobos/blob/allocator/std/experimental/allocator/fallback_allocator.d Once the memory in the front buffer is exhausted, the fallback allocator starts getting used. The correct way to handle the choice in the composer is to first try the front, and if it returns null, defer to the fallback. Many other allocators follow similar patterns.Yeh, failed allocations are relatively frequent within the framework components.I find this surprising.
May 16 2015
On 5/16/15 1:22 PM, Walter Bright wrote:On 5/16/2015 9:34 AM, Andrei Alexandrescu wrote:One more illustration of the same idea: just completed a larger doc. http://erdani.com/d/phobos-prerelease/std_experimental_allocator_kernighan_ritchie.html The Kernighan-Ritchie allocator is composed of a list of blocks, each organized as a free list; when one block gets exhausted, the list detects that and allocates more. AndreiOnce the memory in the front buffer is exhausted, the fallback allocator starts getting used. The correct way to handle the choice in the composer is to first try the front, and if it returns null, defer to the fallback. Many other allocators follow similar patterns.Ah, ok, that makes sense. I was thinking more in terms of the whole program running out of memory, not fallback.
May 16 2015
On 2015-05-15 22:34, Timon Gehr wrote:- Where do you allocate the exception object?Per-allocated? The same way as out of memory is handled in the runtime. -- /Jacob Carlborg
May 16 2015
On 5/16/15 2:20 AM, Jacob Carlborg wrote:On 2015-05-15 22:34, Timon Gehr wrote:Regardless, std.allocator does not use exceptions anywhere (it is, however, neutral to exceptions thrown from withing e.g. constructors of generic types). -- Andrei- Where do you allocate the exception object?Per-allocated? The same way as out of memory is handled in the runtime.
May 16 2015
On 2015-05-16 11:20, Jacob Carlborg wrote:Per-allocated? The same way as out of memory is handled in the runtime.To avoid confusion, that should have been "pre-allocated". -- /Jacob Carlborg
May 16 2015
On Friday, 15 May 2015 at 20:34:13 UTC, Timon Gehr wrote:if (fallbackInstalled) return fallbackAllocate(); else throw OhMyGodException();I do think think this is what makes sense for us: - We should throw in case of error, not return null.- Too much overhead, there might be a fall-back installed. - Where do you allocate the exception object?
May 16 2015
On 05/15/2015 09:49 PM, Andrei Alexandrescu wrote:On 5/15/15 11:51 AM, Andrei Alexandrescu wrote:- Quantizer currently does not necessarily follow this rule. - Might it not be surprising behaviour for AffixAllocator?On 5/15/15 11:37 AM, deadalnix wrote:Well I added the rule that allocate(0) should return null, there are a few more tests but probably nothing worrisome: https://github.com/andralex/phobos/commit/f73f6ecf1b45b0fc3cffd50d375eb15eb2311220 AndreiOn Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Ah, nice. I was under the misconception that malloc(0) cannot return null in C. Apparently it's implementation defined at least since C99, see http://stackoverflow.com/a/2132318/348571. Thanks!This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there.There are actually 2 way to do this in malloc. Either you return null, but then you need to be able to accept null in the free implementation (as malloc must return a freeable pointer) or you just bump to 1. Both are valid per spec and there are implementations of malloc for both.
May 15 2015
On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc. What most malloc() implementations practically do in their first line is: if (size == 0) size = 1; and take it from there. The reasoning was to make failure of malloc easy to test for. This would suffice: size_t s; ... void* p = malloc(s); if (!p) { ... failed! ... } as opposed to: if (!p && s) { ... failed! ... } That kinda makes sense, but it's not super consistent. For example, realloc() does not obey the same protocol. Calling realloc() with a new size of 0 actually free()s the pointer and then returns null. Anyhow, on to D. In D it's easy to test whether an allocation succeeded: auto buf = alloc.allocate(s); if (buf.length != s) { ... failed! ... } It is a bit subtle, but I think overall it makes everyone's life easier. Thoughts? AndreiHow about defining `alloc.allocate(0)` to *be* an error?
May 17 2015
On 05/17/2015 10:35 AM, Idan Arye wrote:... How about defining `alloc.allocate(0)` to *be* an error?What is bad about allocate(0)?
May 17 2015
On Sunday, 17 May 2015 at 12:09:37 UTC, Timon Gehr wrote:On 05/17/2015 10:35 AM, Idan Arye wrote:It's not that allocating 0 bytes is wrong by itself(at first glance it seemed very wrong to me, but then I remembered that you are never allowed to read-from or writ-to it more than 0 bytes), but it's how limited it's usefulness is compared to all the special-casing it requires, it might be better to simply disallow it.... How about defining `alloc.allocate(0)` to *be* an error?What is bad about allocate(0)?
May 17 2015
On 5/17/15 5:27 AM, Idan Arye wrote:On Sunday, 17 May 2015 at 12:09:37 UTC, Timon Gehr wrote:Prolly not a good idea, 0 works well for the most part as a natural lower bound, e.g.: void fun(size_t n) { int[] a = theAllocator.makeArray!int(n); scope(exit) theAllocator.dispose(a); foreach (ref e; a) { ... } .... } Special casing code like this for n==0 (lest functions start throwing etc) is not a good strategy to condone. AndreiOn 05/17/2015 10:35 AM, Idan Arye wrote:It's not that allocating 0 bytes is wrong by itself(at first glance it seemed very wrong to me, but then I remembered that you are never allowed to read-from or writ-to it more than 0 bytes), but it's how limited it's usefulness is compared to all the special-casing it requires, it might be better to simply disallow it.... How about defining `alloc.allocate(0)` to *be* an error?What is bad about allocate(0)?
May 17 2015
On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc.Is the invariant malloc(0) != malloc(0) the only thing that makes 0 a special case here?
May 17 2015
On 5/17/15 7:13 AM, Peter Alexander wrote:On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:I thought so, but apparently C99 _does_ allow malloc(0) to return null, so that's not an invariant :o). Well for now std.allocator will go with null. AndreiThis is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc.Is the invariant malloc(0) != malloc(0) the only thing that makes 0 a special case here?
May 17 2015
On Sunday, 17 May 2015 at 14:13:03 UTC, Peter Alexander wrote:On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Doesn't need to be, the spec only say it must be passable to free.This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc.Is the invariant malloc(0) != malloc(0) the only thing that makes 0 a special case here?
May 17 2015
On Sunday, 17 May 2015 at 20:31:50 UTC, deadalnix wrote:On Sunday, 17 May 2015 at 14:13:03 UTC, Peter Alexander wrote:So here's my question: can we just make allocate(0) do nothing special? i.e. allocate a non-null, but still 0 length buffer?On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Doesn't need to be, the spec only say it must be passable to free.This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc.Is the invariant malloc(0) != malloc(0) the only thing that makes 0 a special case here?
May 18 2015
On 5/18/15 5:16 AM, Peter Alexander wrote:On Sunday, 17 May 2015 at 20:31:50 UTC, deadalnix wrote:Yes, allocation could be rounded to whatever minimum the allocator supports, then a zero-length slice be taken of the result. -- AndreiOn Sunday, 17 May 2015 at 14:13:03 UTC, Peter Alexander wrote:So here's my question: can we just make allocate(0) do nothing special? i.e. allocate a non-null, but still 0 length buffer?On Friday, 15 May 2015 at 16:36:29 UTC, Andrei Alexandrescu wrote:Doesn't need to be, the spec only say it must be passable to free.This is a matter with some history behind it. In C, malloc(0) always returns a new, legit pointer that can be subsequently reallocated, freed etc.Is the invariant malloc(0) != malloc(0) the only thing that makes 0 a special case here?
May 18 2015