www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.allocator.allocate(0) -> return null or std.allocator.allocate(1)?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
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?


 Andrei
There 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
prev sibling next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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:
 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.
Ha! Two fools, one thought :-)
May 15 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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:
 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".
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.
May 15 2015
prev sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
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
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/15/15 6:56 PM, Vladimir Panteleev wrote:
 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.
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
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 16 May 2015 at 02:05:22 UTC, Andrei Alexandrescu 
wrote:
 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
You should, C is just not a language designed for type safety and correctness.
May 15 2015
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
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
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/15/15 11:37 AM, deadalnix wrote:
 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.
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! Andrei
May 15 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/15/15 11:51 AM, Andrei Alexandrescu wrote:
 On 5/15/15 11:37 AM, deadalnix wrote:
 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.
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!
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 Andrei
May 15 2015
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
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

 Andrei
I 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
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 05/15/2015 10:13 PM, deadalnix wrote:
 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


 Andrei
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 15 2015
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/15/15 1:34 PM, Timon Gehr wrote:
 On 05/15/2015 10:13 PM, deadalnix wrote:
 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



 Andrei
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?
Yeh, failed allocations are relatively frequent within the framework components. -- Andrei
May 15 2015
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/16/15 2:07 AM, Walter Bright wrote:
 On 5/15/2015 6:38 PM, Andrei Alexandrescu wrote:
 Yeh, failed allocations are relatively frequent within the framework
 components.
I find this surprising.
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. Andrei
May 16 2015
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/16/2015 9:34 AM, Andrei Alexandrescu wrote:
 On 5/16/15 2:07 AM, Walter Bright wrote:
 On 5/15/2015 6:38 PM, Andrei Alexandrescu wrote:
 Yeh, failed allocations are relatively frequent within the framework
 components.
I find this surprising.
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.
Ah, ok, that makes sense. I was thinking more in terms of the whole program running out of memory, not fallback.
May 16 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/16/15 1:22 PM, Walter Bright wrote:
 On 5/16/2015 9:34 AM, Andrei Alexandrescu wrote:
 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.
Ah, ok, that makes sense. I was thinking more in terms of the whole program running out of memory, not fallback.
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. Andrei
May 16 2015
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
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
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/16/15 2:20 AM, Jacob Carlborg wrote:
 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.
Regardless, std.allocator does not use exceptions anywhere (it is, however, neutral to exceptions thrown from withing e.g. constructors of generic types). -- Andrei
May 16 2015
prev sibling parent Jacob Carlborg <doob me.com> writes:
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
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 15 May 2015 at 20:34:13 UTC, Timon Gehr wrote:
 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?
if (fallbackInstalled) return fallbackAllocate(); else throw OhMyGodException();
May 16 2015
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 05/15/2015 09:49 PM, Andrei Alexandrescu wrote:
 On 5/15/15 11:51 AM, Andrei Alexandrescu wrote:
 On 5/15/15 11:37 AM, deadalnix wrote:
 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.
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!
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 Andrei
- Quantizer currently does not necessarily follow this rule. - Might it not be surprising behaviour for AffixAllocator?
May 15 2015
prev sibling next sibling parent reply "Idan Arye" <GenericNPC gmail.com> writes:
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?


 Andrei
How about defining `alloc.allocate(0)` to *be* an error?
May 17 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
parent reply "Idan Arye" <GenericNPC gmail.com> writes:
On Sunday, 17 May 2015 at 12:09:37 UTC, Timon Gehr wrote:
 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)?
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.
May 17 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/17/15 5:27 AM, Idan Arye wrote:
 On Sunday, 17 May 2015 at 12:09:37 UTC, Timon Gehr wrote:
 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)?
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.
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. Andrei
May 17 2015
prev sibling parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
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
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/17/15 7:13 AM, Peter Alexander wrote:
 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?
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. Andrei
May 17 2015
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
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:
 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?
Doesn't need to be, the spec only say it must be passable to free.
May 17 2015
parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
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:
 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?
Doesn't need to be, the spec only say it must be passable to free.
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?
May 18 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/18/15 5:16 AM, Peter Alexander wrote:
 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:
 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?
Doesn't need to be, the spec only say it must be passable to free.
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?
Yes, allocation could be rounded to whatever minimum the allocator supports, then a zero-length slice be taken of the result. -- Andrei
May 18 2015