Thread overview
Stack allocation of dynamic arrays?
Aug 08, 2007
Robert Fraser
Aug 08, 2007
Xinok
Aug 08, 2007
Kirk McDonald
Aug 08, 2007
Sean Kelly
Aug 10, 2007
Robert Fraser
Aug 14, 2007
Manfred Nowak
August 08, 2007
I know that by using "scope" you can allocate a class on the stack rather than the heap. For this line:

scope int[] arr = new int[5000];

... is arr allocated on the heap or on the stack?
August 08, 2007
That would be allocated on the heap. If you want to allocate on the stack, use a static array:
int[5000] arr;

There's no need for the 'scope' keyword there, it's automatically allocated on the stack.

Robert Fraser wrote:
> I know that by using "scope" you can allocate a class on the stack rather than the heap. For this line:
> 
> scope int[] arr = new int[5000];
> 
> ... is arr allocated on the heap or on the stack?
August 08, 2007
Robert Fraser wrote:
> I know that by using "scope" you can allocate a class on the stack rather than the heap. For this line:
> 
> scope int[] arr = new int[5000];
> 
> ... is arr allocated on the heap or on the stack?

The spec implies it should be on the stack:

"If a NewExpression is used as an initializer for a function local variable with scope storage class, and the ArgumentList to new is empty, then the instance is allocated on the stack rather than the heap or using the class specific allocator."

Even if it isn't actually on the stack, it behaves exactly as though it were.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
August 08, 2007
Kirk McDonald wrote:
> Robert Fraser wrote:
>> I know that by using "scope" you can allocate a class on the stack rather than the heap. For this line:
>>
>> scope int[] arr = new int[5000];
>>
>> ... is arr allocated on the heap or on the stack?
> 
> The spec implies it should be on the stack:
> 
> "If a NewExpression is used as an initializer for a function local variable with scope storage class, and the ArgumentList to new is empty, then the instance is allocated on the stack rather than the heap or using the class specific allocator."
> 
> Even if it isn't actually on the stack, it behaves exactly as though it were.

I think this is what should happen according to the spec, but I'm not sure that it's what actually happens in practice.  I tried running this app:

    char[] pstr;

    void go()
    {
        scope char[] lstr = new char[5];
        lstr[] = "hello";
        pstr = lstr;
    }

    void main()
    {
        go();
        printf( "%.*s\n", pstr );
    }

and it printed "hello".  So to investigate what was actually happening I  dumped the asm code for go():

    _D4test2goFZv	comdat
    	assume	CS:_D4test2goFZv
    L0:		enter	8,0
    		push	5
    		push	offset FLAT:_D11TypeInfo_Aa6__initZ
    		call	near ptr __d_newarrayiT
    		mov	-8[EBP],EAX
    		mov	-4[EBP],EDX
    		push	EDX
    		push	EAX
    		push	dword ptr FLAT:_DATA[0Ch]
    		push	dword ptr FLAT:_DATA[08h]
    		push	1
    		call	near ptr __d_arraycopy
    		mov	EDX,-4[EBP]
    		mov	EAX,-8[EBP]
    		mov	_D4test4pstrAa,EAX
    		mov	_D4test4pstrAa[04h],EDX
    		add	ESP,01Ch
    		leave
    		ret
    _D4test2goFZv	ends

As you can see, __d_newarrayiT is called to allocate dynamic memory for lstr, "hello" is copied into this memory by __d_arraycopy, pstr reassigned, and then the function returns.  There is no delete operation which indicates the memory is actually destroyed.

In light of the above, I think the current behavior of the 'scope' keyword only applies to classes.  This should possibly be filed as a bug either for the compiler or the spec.


Sean
August 10, 2007
Sean Kelly Wrote:

> Kirk McDonald wrote:
> > Robert Fraser wrote:
> >> I know that by using "scope" you can allocate a class on the stack rather than the heap. For this line:
> >>
> >> scope int[] arr = new int[5000];
> >>
> >> ... is arr allocated on the heap or on the stack?
> > 
> > The spec implies it should be on the stack:
> > 
> > "If a NewExpression is used as an initializer for a function local variable with scope storage class, and the ArgumentList to new is empty, then the instance is allocated on the stack rather than the heap or using the class specific allocator."
> > 
> > Even if it isn't actually on the stack, it behaves exactly as though it were.
> 
> I think this is what should happen according to the spec, but I'm not sure that it's what actually happens in practice.  I tried running this app:
> 
>      char[] pstr;
> 
>      void go()
>      {
>          scope char[] lstr = new char[5];
>          lstr[] = "hello";
>          pstr = lstr;
>      }
> 
>      void main()
>      {
>          go();
>          printf( "%.*s\n", pstr );
>      }
> 
> and it printed "hello".  So to investigate what was actually happening I
>   dumped the asm code for go():
> 
>      _D4test2goFZv	comdat
>      	assume	CS:_D4test2goFZv
>      L0:		enter	8,0
>      		push	5
>      		push	offset FLAT:_D11TypeInfo_Aa6__initZ
>      		call	near ptr __d_newarrayiT
>      		mov	-8[EBP],EAX
>      		mov	-4[EBP],EDX
>      		push	EDX
>      		push	EAX
>      		push	dword ptr FLAT:_DATA[0Ch]
>      		push	dword ptr FLAT:_DATA[08h]
>      		push	1
>      		call	near ptr __d_arraycopy
>      		mov	EDX,-4[EBP]
>      		mov	EAX,-8[EBP]
>      		mov	_D4test4pstrAa,EAX
>      		mov	_D4test4pstrAa[04h],EDX
>      		add	ESP,01Ch
>      		leave
>      		ret
>      _D4test2goFZv	ends
> 
> As you can see, __d_newarrayiT is called to allocate dynamic memory for lstr, "hello" is copied into this memory by __d_arraycopy, pstr reassigned, and then the function returns.  There is no delete operation which indicates the memory is actually destroyed.
> 
> In light of the above, I think the current behavior of the 'scope' keyword only applies to classes.  This should possibly be filed as a bug either for the compiler or the spec.
> 
> 
> Sean

That's what I wanted to know, thanks.
August 14, 2007
Sean Kelly wrote

> In light of the above, I think the current behavior of the 'scope' keyword only applies to classes.  This should possibly be filed as a bug either for the compiler or the spec.

In addition, as I just detected, space occupied by dynamic arrays is not deleted on exit of scope.

-manfred