Jump to page: 1 2
Thread overview
array construction without heap alloc
Dec 21, 2007
Frank Benoit
Dec 22, 2007
0ffh
Dec 22, 2007
0ffh
Dec 22, 2007
Frank Benoit
Dec 22, 2007
Frank Benoit
Dec 22, 2007
0ffh
Dec 24, 2007
0ffh
Dec 22, 2007
0ffh
Dec 22, 2007
0ffh
Dec 22, 2007
Derek Parnell
December 21, 2007
With D1:

I have a function with this unchangable signature:

  void func( int[] a ){} // will not store the array ref

Now i want to pass in some non-const integer values:

  void bar( int a, int b ){
    func( [ a, b ] );
  }

My problem is, i want to do it without heap allocation. So I can do this:

  void bar( int a, int b ){
    int[2] arr;
    arr[0] = a;
    arr[1] = b;
    func( arr );
  }

This works, but the syntax sucks.
Any suggestions?


December 22, 2007
Frank Benoit wrote:
> My problem is, i want to do it without heap allocation. So I can do this:
> 
>   void bar( int a, int b ){
>     int[2] arr;
>     arr[0] = a;
>     arr[1] = b;
>     func( arr );
>   }

I don't know, but I'd guess this would also not allocate heap:

void bar( int a, int b )
{
  int[2] arr=[a,b];
  func( arr );
}

regards, frank
December 22, 2007
I compiled this using D1 (DMD):

  void bar( int a, int b )
  {
    int[2] arr=[a,b];
    int brr;
    int[] crr;
    crr.length=2;
    func( arr );
    printf("%p %p\n",&arr,arr.ptr);
    printf("%p\n",&brr);
    printf("%p %p\n",&crr,crr.ptr);
  }

It gives me &arr==arr.ptr, which is near &brr and &crr,
while crr.ptr is somewhere completely different.
I suppose that kinda proofs it. =)
Hope it's helpful.

regards, frank
December 22, 2007
0ffh schrieb:
> 
> I compiled this using D1 (DMD):
> 
>   void bar( int a, int b )
>   {
>     int[2] arr=[a,b];
>     int brr;
>     int[] crr;
>     crr.length=2;
>     func( arr );
>     printf("%p %p\n",&arr,arr.ptr);
>     printf("%p\n",&brr);
>     printf("%p %p\n",&crr,crr.ptr);
>   }
> 
> It gives me &arr==arr.ptr, which is near &brr and &crr,
> while crr.ptr is somewhere completely different.
> I suppose that kinda proofs it. =)
> Hope it's helpful.
> 
> regards, frank

Sorry, but this does a heap allocation. I forgot to mention how i detect it. I used obj2asm to get the assembly of the object file. Using the array literal will cause a call to the d runtime _d_arrayliteralT function, which uses heap allocation.

On IRC "Hxal" posted a template magic solution. It goes like this:

struct StaticArray(T, size_t S){
	T[S] array;
}
StaticArray!(typeof(T[0]), T.length) staticArray(T...)(T values){
	StaticArray!(typeof(T[0]), T.length) x;
	foreach(i,v; values)
		x.array[i] = v;
	return x;
}

Usage is:

  void bar( int a, int b ){
    func( staticArray( a, b ).array )
  }

I wonder why arrayliterals are allocated on the heap.
You always have the .dup option.
December 22, 2007
"Frank Benoit" <keinfarbton@googlemail.com> wrote in message news:fkj3oe$2qcm$1@digitalmars.com...

> I wonder why arrayliterals are allocated on the heap.

Probably to prevent otherwise very common errors like:

void foo(int x, int y)
{
    someGlobal = [x, y];
}

int[] bar(int x, int y)
{
    return [x, y];
}

i.e. escaping references to a locally-allocated array.

Before anyone says "but the compiler could detect those", what about in this case:

extern(C) someFunc(int* arr, int len);

void myFunc(int x, int y)
{
    auto arr = [x, y];
    someFunc(arr.ptr, arr.length);
}

The compiler knows nothing about what someFunc does and can't tell if it stores that array away in some global variable or something, therefore it can't tell if this is legal code.  (This is why side effects are bad, the FP programmers tell us..)


December 22, 2007
Jarrett Billingsley schrieb:
> "Frank Benoit" <keinfarbton@googlemail.com> wrote in message news:fkj3oe$2qcm$1@digitalmars.com...
> 
>> I wonder why arrayliterals are allocated on the heap.
> 
> Probably to prevent otherwise very common errors like:
> 
> void foo(int x, int y)
> {
>     someGlobal = [x, y];
> }
> 
> int[] bar(int x, int y)
> {
>     return [x, y];
> }
> 
> i.e. escaping references to a locally-allocated array.
> 

So it is exaclty the same situation how it is with pointers to local function in D1 compared to D2.

In D1 you need to know what to do, in D2 there is no way around the heap.
December 22, 2007
Frank Benoit wrote:
> I wonder why arrayliterals are allocated on the heap.
> You always have the .dup option.

That's really unfortunate, especially as the array does
quite definitely end up on the stack. So with a static
array and an array literal you would get the worst of
both worlds. I'll investigate that.

regards, frank
December 22, 2007
Jarrett Billingsley wrote:
> Before anyone says "but the compiler could detect those", what about in this case:

It would be quite enough if it detected that it's initialising a static
array on the stack, as in the example. That's what I'd have expected.

regards, frank
December 22, 2007
0ffh wrote:
> That's really unfortunate, especially as the array does
> quite definitely end up on the stack. So with a static
> array and an array literal you would get the worst of
> both worlds. I'll investigate that.

Yup, it seems to eat memory, that's a bad sign!
Sorry for misleading you, but this is really unexpected!

regards, frank
December 22, 2007
On Fri, 21 Dec 2007 21:25:31 +0100, Frank Benoit wrote:

This below seems to work...

import std.stdio;
void func( int[] a )
{
    writefln("a's address = %08p", a.ptr);

}

void bar( int a, int b ){
    int c;
    writefln("c's address = %08p", &c);

    scope int[2]f = [a,b];
    func(f);
}

void main()
{
    bar(1,2);
}

However the syntax is not as neat as you'd like it I guess.

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
« First   ‹ Prev
1 2