Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 13, 2017 Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
import std.random; import std.stdio; int[4] testfunc(int num) @nogc { return [0, 1, num, 3]; } int main() { int[4] arr = testfunc(uniform(0, 15)); writeln(arr); return 0; } I've read a bunch of stuff that seems to indicate that array literals are always heap-allocated, even when being used to populate a static array. However, testfunc() above compiles as @nogc. This would indicate to me that D does the smart thing and avoids a heap allocation for an array literal being used to populate a static array. Is all the old stuff I was reading just out-of-date now? |
May 13, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lewis | On Saturday, 13 May 2017 at 18:32:16 UTC, Lewis wrote: > import std.random; > import std.stdio; > > int[4] testfunc(int num) @nogc > { > return [0, 1, num, 3]; > } > > int main() > { > int[4] arr = testfunc(uniform(0, 15)); > writeln(arr); > return 0; > } > > I've read a bunch of stuff that seems to indicate that array literals are always heap-allocated, even when being used to populate a static array. On the contrary, when initializing static arrays, allocation is not needed. Note that what's *conceptually* happening in testfunc is this: >int[4] testfunc(int num) @nogc >{ > typeof(return) result = [0, 1, num, 3]; > return result; >} i.e. the type and size of the storage is known beforehand, all there is to do is copy the elements: 000000000044e528 <@nogc int[4] test.testfunc(int)>: 44e528: 55 push %rbp 44e529: 48 8b ec mov %rsp,%rbp 44e52c: 48 83 ec 10 sub $0x10,%rsp 44e530: 48 89 7d f8 mov %rdi,-0x8(%rbp) 44e534: c7 07 00 00 00 00 movl $0x0,(%rdi) # 0 goes at offset 0 44e53a: c7 47 04 01 00 00 00 movl $0x1,0x4(%rdi) # 1 at offset 4 44e541: 89 77 08 mov %esi,0x8(%rdi) # parameter at offset 8 44e544: c7 47 0c 03 00 00 00 movl $0x3,0xc(%rdi) # 3 at offset 12 44e54b: 48 8b 45 f8 mov -0x8(%rbp),%rax 44e54f: c9 leaveq 44e550: c3 retq > Is all the old stuff I was reading just out-of-date now? Where exactly did you read that initialization of a static array requires an allocation? That source should be abolished... errrm... corrected! |
May 13, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lewis | On Saturday, 13 May 2017 at 18:32:16 UTC, Lewis wrote:
> import std.random;
> import std.stdio;
>
> int[4] testfunc(int num) @nogc
> {
> return [0, 1, num, 3];
> }
>
> int main()
> {
> int[4] arr = testfunc(uniform(0, 15));
> writeln(arr);
> return 0;
> }
>
> I've read a bunch of stuff that seems to indicate that array literals are always heap-allocated, even when being used to populate a static array. However, testfunc() above compiles as @nogc. This would indicate to me that D does the smart thing and avoids a heap allocation for an array literal being used to populate a static array. Is all the old stuff I was reading just out-of-date now?
It's just out of date. Can't remember the version, but this did use to allocate. It doesn't any more. But only for this case. In most cases it does allocate.
-Steve
|
May 13, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lewis | On Saturday, 13 May 2017 at 18:32:16 UTC, Lewis wrote:
> import std.random;
> import std.stdio;
>
> int[4] testfunc(int num) @nogc
> {
> return [0, 1, num, 3];
> }
>
> int main()
> {
> int[4] arr = testfunc(uniform(0, 15));
> writeln(arr);
> return 0;
> }
>
> I've read a bunch of stuff that seems to indicate that array literals are always heap-allocated, even when being used to populate a static array. However, testfunc() above compiles as @nogc. This would indicate to me that D does the smart thing and avoids a heap allocation for an array literal being used to populate a static array. Is all the old stuff I was reading just out-of-date now?
1D arrays it doesn't, 2D or higher it does.
|
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Saturday, 13 May 2017 at 19:22:09 UTC, Steven Schveighoffer wrote: > It's just out of date. Can't remember the version, but this did use to allocate. It doesn't any more. But only for this case. In most cases it does allocate. Okay cool, that's good to hear. For reference the most recent place I remember seeing this was http://stackoverflow.com/questions/6751575/how-to-initialise-static-arrays-in-d-without-a-gc-allocation (although I've definitely seen others in the past). I'll add an answer to the SO question to clarify that this is no longer an issue. Thanks all! |
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lewis | On Sunday, 14 May 2017 at 01:15:03 UTC, Lewis wrote:
> On Saturday, 13 May 2017 at 19:22:09 UTC, Steven Schveighoffer wrote:
>> It's just out of date. Can't remember the version, but this did use to allocate. It doesn't any more. But only for this case. In most cases it does allocate.
>
> Okay cool, that's good to hear. For reference the most recent place I remember seeing this was http://stackoverflow.com/questions/6751575/how-to-initialise-static-arrays-in-d-without-a-gc-allocation (although I've definitely seen others in the past). I'll add an answer to the SO question to clarify that this is no longer an issue.
>
> Thanks all!
You could also use something like this:
----
auto s(T, size_t n)(T[n] arr)
{
return arr;
}
auto is = [1, 2, 3].s; // stack allocated
----
I use it whenever I work with D.
|
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lewis | On Sunday, 14 May 2017 at 01:15:03 UTC, Lewis wrote:
> On Saturday, 13 May 2017 at 19:22:09 UTC, Steven Schveighoffer wrote:
>> It's just out of date. Can't remember the version, but this did use to allocate. It doesn't any more. But only for this case. In most cases it does allocate.
>
> Okay cool, that's good to hear. For reference the most recent place I remember seeing this was http://stackoverflow.com/questions/6751575/how-to-initialise-static-arrays-in-d-without-a-gc-allocation (although I've definitely seen others in the past). I'll add an answer to the SO question to clarify that this is no longer an issue.
>
> Thanks all!
It may allocate if it is returned. I think it elided for one caller because it constructs into the callers stack frame but only if the length of all return path are the same length. For 2D or higher it always allocates, i think.
|
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 05/14/2017 01:57 AM, Nicholas Wilson wrote:
> 1D arrays it doesn't, 2D or higher it does.
What do you mean? This works just fine as well:
----
import std.random;
import std.stdio;
int[2][2] testfunc(int num) @nogc
{
return [[0, 1], [num, 3]];
}
int main()
{
int[2][2] arr = testfunc(uniform(0, 15));
writeln(arr);
return 0;
}
----
|
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Sunday, 14 May 2017 at 10:18:40 UTC, ag0aep6g wrote:
> On 05/14/2017 01:57 AM, Nicholas Wilson wrote:
>> 1D arrays it doesn't, 2D or higher it does.
>
> What do you mean? This works just fine as well:
>
> ----
> import std.random;
> import std.stdio;
>
> int[2][2] testfunc(int num) @nogc
> {
> return [[0, 1], [num, 3]];
> }
>
> int main()
> {
> int[2][2] arr = testfunc(uniform(0, 15));
> writeln(arr);
> return 0;
> }
> ----
dynamic array literals is what I meant.
|
May 14, 2017 Re: Do array literals still always allocate? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 05/14/2017 01:40 PM, Nicholas Wilson wrote:
> dynamic array literals is what I meant.
I don't follow. Can you give an example in code?
|
Copyright © 1999-2021 by the D Language Foundation