Re: Do array literals still always allocate?

2017-05-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/14/17 7:40 AM, Nicholas Wilson wrote:

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.


dynamic array literals allocate most of the time. The one time they 
don't is the specialized case of initializing a static array, I think of 
any dimension.


However, to the OP's point, they *did* allocate up until a certain 
version, even when initializing a static array.


That is:

int[2] x = [1, 2];

used to allocate a dynamic array on the heap, and then copy the data 
into x (and leave the allocated data for the GC). Now it just populates 
x without allocating.


LDC might be smarter, and take more valid shortcuts, so that is good. 
But in general you can expect array literals to allocate when not used 
as static array initializers.


-Steve


Re: Do array literals still always allocate?

2017-05-14 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 14 May 2017 at 12:02:03 UTC, Eugene Wissner wrote:

On Sunday, 14 May 2017 at 11:45:12 UTC, ag0aep6g wrote:

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?


void main()
{
ubyte[] arr = [ 1, 2, 3, 4, 5 ];

assert(arr == [ 1, 2, 3, 4, 5 ]);
}

Both, assignment and comparison, allocate.


LDC is able to promote those to alloca, not sure about DMD or its 
interaction with @nogc.
see 
https://github.com/ldc-developers/ldc/blob/master/gen/passes/GarbageCollect2Stack.cpp#L832 for the details.


Re: Do array literals still always allocate?

2017-05-14 Thread ag0aep6g via Digitalmars-d-learn

On 05/14/2017 02:02 PM, Eugene Wissner wrote:

void main()
{
ubyte[] arr = [ 1, 2, 3, 4, 5 ];

assert(arr == [ 1, 2, 3, 4, 5 ]);
}

Both, assignment and comparison, allocate.


Sure, but Nicholas said 1D arrays behave different from 2D arrays.


Re: Do array literals still always allocate?

2017-05-14 Thread Eugene Wissner via Digitalmars-d-learn

On Sunday, 14 May 2017 at 11:45:12 UTC, ag0aep6g wrote:

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?


void main()
{
ubyte[] arr = [ 1, 2, 3, 4, 5 ];

assert(arr == [ 1, 2, 3, 4, 5 ]);
}

Both, assignment and comparison, allocate.


Re: Do array literals still always allocate?

2017-05-14 Thread ag0aep6g via Digitalmars-d-learn

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?


Re: Do array literals still always allocate?

2017-05-14 Thread Nicholas Wilson via Digitalmars-d-learn

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.


Re: Do array literals still always allocate?

2017-05-14 Thread ag0aep6g via Digitalmars-d-learn

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;
}



Re: Do array literals still always allocate?

2017-05-14 Thread Nicholas Wilson via Digitalmars-d-learn

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.


Re: Do array literals still always allocate?

2017-05-14 Thread Namespace via Digitalmars-d-learn

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.


Re: Do array literals still always allocate?

2017-05-13 Thread Lewis via Digitalmars-d-learn
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!




Re: Do array literals still always allocate?

2017-05-13 Thread Nicholas Wilson via Digitalmars-d-learn

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.


Re: Do array literals still always allocate?

2017-05-13 Thread Steven Schveighoffer via Digitalmars-d-learn

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



Re: Do array literals still always allocate?

2017-05-13 Thread Stanislav Blinov via Digitalmars-d-learn

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:


0044e528 <@nogc int[4] test.testfunc(int)>:
  44e528:   55  push   %rbp
  44e529:   48 8b ecmov%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 00movl   $0x1,0x4(%rdi)   # 
1 at offset 4
  44e541:   89 77 08mov%esi,0x8(%rdi)   # 
parameter at offset 8
  44e544:   c7 47 0c 03 00 00 00movl   $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!