Thread overview
Allocating a slice object
Jul 04, 2013
monarch_dodra
Jul 04, 2013
Maxim Fomin
Jul 04, 2013
monarch_dodra
Jul 08, 2013
Marco Leise
Jul 08, 2013
monarch_dodra
Jul 04, 2013
Jonathan M Davis
July 04, 2013
This is a pretty stupid question, but how would you allocate an "int[]" on the heap? I'm not talking about the array, but the actual slice object. EG:

int[]* pSlice = new int[];
//Error: new can only create structs,
//dynamic arrays or class objects, not int[]'s

Is there a simple "idiomatic" way?

I'm currently doing it by allocating a struct that wraps one:

struct S{int[] a;}
int[]* pSlice1 = cast(int[]*) new S;
int[]* pSlice2 = &(new S).a;

Note: This is also a neat way to allocate a static array on the heap.

Anybody have some better way?
July 04, 2013
On Thursday, 4 July 2013 at 12:02:16 UTC, monarch_dodra wrote:
> This is a pretty stupid question, but how would you allocate an "int[]" on the heap? I'm not talking about the array, but the actual slice object. EG:
>
> int[]* pSlice = new int[];
> //Error: new can only create structs,
> //dynamic arrays or class objects, not int[]'s
>
> Is there a simple "idiomatic" way?
>
> I'm currently doing it by allocating a struct that wraps one:
>
> struct S{int[] a;}
> int[]* pSlice1 = cast(int[]*) new S;
> int[]* pSlice2 = &(new S).a;
>
> Note: This is also a neat way to allocate a static array on the heap.

Yes. This is a good example of how D type system and memory allocation type are different, despite many move type system terms into memory category.

> Anybody have some better way?

Another way:

import std.stdio;

void main()
{
	int[] arr;
	auto x = { return arr; } ;
	writeln(&arr);
}
July 04, 2013
On Thu, 04 Jul 2013 08:02:13 -0400, monarch_dodra <monarchdodra@gmail.com> wrote:

> This is a pretty stupid question, but how would you allocate an "int[]" on the heap? I'm not talking about the array, but the actual slice object. EG:
>
> int[]* pSlice = new int[];
> //Error: new can only create structs,
> //dynamic arrays or class objects, not int[]'s
>
> Is there a simple "idiomatic" way?

Not really.  There was talk at one point of deprecating that version, so you had to do new int[](5) instead of new int[5], and then using new int[5] to mean new "fixed sized array of size 5 on the heap", and then new int[] would mean new slice on the heap.

But I think there's a real lack of benefit to this, plus it would be confusing to people familiar with other languages.

> I'm currently doing it by allocating a struct that wraps one:
>
> struct S{int[] a;}
> int[]* pSlice1 = cast(int[]*) new S;
> int[]* pSlice2 = &(new S).a;
>
> Note: This is also a neat way to allocate a static array on the heap.
>
> Anybody have some better way?

This should work:

int[] *pSlice = (new int[][1]).ptr;

-Steve
July 04, 2013
On Thursday, 4 July 2013 at 13:37:52 UTC, Steven Schveighoffer wrote:
> On Thu, 04 Jul 2013 08:02:13 -0400, monarch_dodra <monarchdodra@gmail.com> wrote:
>
>> This is a pretty stupid question, but how would you allocate an "int[]" on the heap? I'm not talking about the array, but the actual slice object. EG:
>>
>> int[]* pSlice = new int[];
>> //Error: new can only create structs,
>> //dynamic arrays or class objects, not int[]'s
>>
>> Is there a simple "idiomatic" way?
>
> Not really.  There was talk at one point of deprecating that version, so you had to do new int[](5) instead of new int[5], and then using new int[5] to mean new "fixed sized array of size 5 on the heap", and then new int[] would mean new slice on the heap.
>
> But I think there's a real lack of benefit to this, plus it would be confusing to people familiar with other languages.

One advantage I see is that it is a way to allocate a fixed amount of objects in memory in heap, without having to add the Appendable info.

But that change would require changing an existing semantic, so fat chances of that happening now.

>> I'm currently doing it by allocating a struct that wraps one:
>>
>> struct S{int[] a;}
>> int[]* pSlice1 = cast(int[]*) new S;
>> int[]* pSlice2 = &(new S).a;
>>
>> Note: This is also a neat way to allocate a static array on the heap.
>>
>> Anybody have some better way?
>
> This should work:
>
> int[] *pSlice = (new int[][1]).ptr;
>
> -Steve

Hum... That would allocate a dynamic array of slices though right? There'd be the Appendable overhead for just one element...
July 04, 2013
On Thursday, July 04, 2013 09:37:57 Steven Schveighoffer wrote:
> On Thu, 04 Jul 2013 08:02:13 -0400, monarch_dodra <monarchdodra@gmail.com>
> 
> wrote:
> > This is a pretty stupid question, but how would you allocate an "int[]" on the heap? I'm not talking about the array, but the actual slice object. EG:
> > 
> > int[]* pSlice = new int[];
> > //Error: new can only create structs,
> > //dynamic arrays or class objects, not int[]'s
> > 
> > Is there a simple "idiomatic" way?
> 
> Not really.  There was talk at one point of deprecating that version, so you had to do new int[](5) instead of new int[5], and then using new int[5] to mean new "fixed sized array of size 5 on the heap", and then new int[] would mean new slice on the heap.
> 
> But I think there's a real lack of benefit to this, plus it would be confusing to people familiar with other languages.

If we were to make such a change, I'd argue for making int[5] outright illegal simply because it _would_ be too confusing for folks from other languages, but I really do wish that what we had with arrays was cleaner in this respect. We kind of get away with new int[5] and new int[](5) being the same thing, but then everyone is thrown off once you go to another level - e.g. new int[5][2]. So, I think that D's apporoach to this was a definite mistake. But also going full-out and making it so that every time the number is between the brackets, it's a static array, and every time it's between the parens it's a dynamic array isn't exactly pretty either - particularly given the confusion around the common use case. So, I don't know quite what we should have done. It almost makes me think that static arrays should have outright not used brackets.

In any case, we're pretty much stuck with what we have at this point, regardless of what the ideal solution would have been.

- Jonathan M Davis
July 08, 2013
Am Thu, 04 Jul 2013 15:54:48 +0200
schrieb "monarch_dodra" <monarchdodra@gmail.com>:

> > This should work:
> >
> > int[] *pSlice = (new int[][1]).ptr;
> >
> > -Steve
> 
> Hum... That would allocate a dynamic array of slices though right? There'd be the Appendable overhead for just one element...

No, it allocates a static one-element array of int[]s and then returns the pointer to the first and only element. It's similar to wrapping it in a struct. So +1 for that solution.

-- 
Marco

July 08, 2013
On Monday, 8 July 2013 at 15:43:21 UTC, Marco Leise wrote:
> Am Thu, 04 Jul 2013 15:54:48 +0200
> schrieb "monarch_dodra" <monarchdodra@gmail.com>:
>
>> > This should work:
>> >
>> > int[] *pSlice = (new int[][1]).ptr;
>> >
>> > -Steve
>> 
>> Hum... That would allocate a dynamic array of slices though right? There'd be the Appendable overhead for just one element...
>
> No, it allocates a static one-element array of int[]s and then
> returns the pointer to the first and only element. It's
> similar to wrapping it in a struct. So +1 for that solution.

I don't think that allocates a static array, it's just an alternative syntax for dynamic array allocation. The fact that you are extracting a pointer from it and it only has a single element doesn't mean it is a static array.

//----
void main()
{
    int[]* pSlice = (new int[][4]).ptr;
    writeln(pSlice[0 .. 4].capacity);
}
//----

This prints 7 for me, which would simply be impossible for new was allocating a static array.