Thread overview
Bizarre way to 'new' arrays
Jun 16, 2006
Sean Kelly
Jun 16, 2006
Gregor Richards
Jun 16, 2006
Lionello Lunesu
Jun 16, 2006
Gregor Richards
Jun 16, 2006
Tom S
Jun 16, 2006
BCS
Jun 16, 2006
Frits van Bommel
Jun 16, 2006
BCS
Jun 16, 2006
James Dunne
June 16, 2006
I was looking through parse.c again, and in the ::parseNewExp() function, I noticed something odd.  Interested, I typed this in:

int[] x = new int[](4);

And it compiles and runs.  Writing

writefln(x.length);

displays 4.

This is legal because a NewExpression can be defined as

'new' [(ArgumentList)] Type (ArgumentList)

So in the case of 'new int[](4)', int[] is parsed as the Type and the (4) is parsed as the argument list.  In fact, writing 'new int[4]' is just syntactic sugar for 'new int[](4)'.  This makes sense, as when you new an array (or anything for that matter), you're really calling a function.

Sorry if this is a bit OT, but I thought it was interesting.


June 16, 2006
Jarrett Billingsley wrote:
> I was looking through parse.c again, and in the ::parseNewExp() function, I noticed something odd.  Interested, I typed this in:
> 
> int[] x = new int[](4);
> 
> And it compiles and runs.  Writing
> 
> writefln(x.length);
> 
> displays 4.
> 
> This is legal because a NewExpression can be defined as
> 
> 'new' [(ArgumentList)] Type (ArgumentList)
> 
> So in the case of 'new int[](4)', int[] is parsed as the Type and the (4) is parsed as the argument list.  In fact, writing 'new int[4]' is just syntactic sugar for 'new int[](4)'.  This makes sense, as when you new an array (or anything for that matter), you're really calling a function.

Sadly, this isn't legal:

    int* i = new int(5);

To allocate and initialize an integer.  AFAIK there's no way around having the assignment as a separate statement following the allocation.


Sean
June 16, 2006
Sean Kelly wrote:
> Jarrett Billingsley wrote:
> 
>> I was looking through parse.c again, and in the ::parseNewExp() function, I noticed something odd.  Interested, I typed this in:
>>
>> int[] x = new int[](4);
>>
>> And it compiles and runs.  Writing
>>
>> writefln(x.length);
>>
>> displays 4.
>>
>> This is legal because a NewExpression can be defined as
>>
>> 'new' [(ArgumentList)] Type (ArgumentList)
>>
>> So in the case of 'new int[](4)', int[] is parsed as the Type and the (4) is parsed as the argument list.  In fact, writing 'new int[4]' is just syntactic sugar for 'new int[](4)'.  This makes sense, as when you new an array (or anything for that matter), you're really calling a function.
> 
> 
> Sadly, this isn't legal:
> 
>     int* i = new int(5);
> 
> To allocate and initialize an integer.  AFAIK there's no way around having the assignment as a separate statement following the allocation.
> 
> 
> Sean


int* i = (new int[5]).ptr;

 - Gregor Richards
June 16, 2006
> int* i = (new int[5]).ptr;

No, he wants to allocate 1 int and initialize it to 5.. Exactly what the code would do in C++:

// allocate 1 int and initialize it to 5
int* i = int(5);

(I found this out when I had to hunt a bug once and it turned out somebody had used (5) instead of [5] )

L.
June 16, 2006
Sean Kelly wrote:
> Sadly, this isn't legal:
> 
>     int* i = new int(5);
> 
> To allocate and initialize an integer.  AFAIK there's no way around having the assignment as a separate statement following the allocation.

int* i = (new int)[0..1] = 5;


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
June 16, 2006
Jarrett Billingsley wrote:
> I was looking through parse.c again, and in the ::parseNewExp() function, I noticed something odd.  Interested, I typed this in:
> 
> int[] x = new int[](4);
> 
> And it compiles and runs.  Writing
> 
> writefln(x.length);
> 
> displays 4.
> 
> This is legal because a NewExpression can be defined as
> 
> 'new' [(ArgumentList)] Type (ArgumentList)
> 
> So in the case of 'new int[](4)', int[] is parsed as the Type and the (4) is parsed as the argument list.  In fact, writing 'new int[4]' is just syntactic sugar for 'new int[](4)'.  This makes sense, as when you new an array (or anything for that matter), you're really calling a function.
> 
> Sorry if this is a bit OT, but I thought it was interesting. 
> 
> 

There's a lot more than that in the parser code!  Start playing around with declarations; you can make some really scary code out of that stuff.

Some of these cases are invalidated by the semantic analyzer, while others pass right through.  It really depends on the specialization of the syntax involved.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M--@ V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++
------END GEEK CODE BLOCK------

James Dunne
June 16, 2006
Tom S wrote:
> Sean Kelly wrote:
> 
>> Sadly, this isn't legal:
>>
>>     int* i = new int(5);
>>
>> To allocate and initialize an integer.  AFAIK there's no way around having the assignment as a separate statement following the allocation.
> 
> 
> int* i = (new int)[0..1] = 5;
> 
>

import std.stdio;

void main()
{		// works for more than one value
	const static int[] store = [0,1,2,3,4,5,6,7,8,9];

		// get a value
	int* i = store[5..6].dup.ptr;
	writef(*i,\n);

		// change it
	*i = 4;
	writef(*i,\n);

		// original is unchanged
	i = store[5..6].dup.ptr;
	writef(*i,\n);
}
June 16, 2006
Lionello Lunesu wrote:
>> int* i = (new int[5]).ptr;
> 
> 
> No, he wants to allocate 1 int and initialize it to 5.. Exactly what the code would do in C++:
> 
> // allocate 1 int and initialize it to 5
> int* i = int(5);
> 
> (I found this out when I had to hunt a bug once and it turned out somebody had used (5) instead of [5] )
> 
> L.

Oh, sorry, misunderstood :)

 - Gregor Richards
June 16, 2006
BCS wrote:
> Tom S wrote:
>> Sean Kelly wrote:
>>
>>> Sadly, this isn't legal:
>>>
>>>     int* i = new int(5);
>>>
>>> To allocate and initialize an integer.  AFAIK there's no way around having the assignment as a separate statement following the allocation.
>>
>>
>> int* i = (new int)[0..1] = 5;
>>
>>
> 
> import std.stdio;
> 
> void main()
> {        // works for more than one value
>     const static int[] store = [0,1,2,3,4,5,6,7,8,9];
> 
>         // get a value
>     int* i = store[5..6].dup.ptr;
>     writef(*i,\n);
> 
>         // change it
>     *i = 4;
>     writef(*i,\n);
> 
>         // original is unchanged
>     i = store[5..6].dup.ptr;
>     writef(*i,\n);
> }

Now try replacing this one:

int* bytes = new int(1024*1024);	// 1 MB

Doesn't scale all that well, does it? :P
June 16, 2006
Frits van Bommel wrote:
> BCS wrote:
>>
[...]
>>
> 
> 
> Now try replacing this one:
> 
> int* bytes = new int(1024*1024);    // 1 MB
> 
> Doesn't scale all that well, does it? :P

If you want an int[2^20] this wont do it. But if you want a dynamically created int that holds that value, that can be done.
For a huge array, I'd ship it mapped into a data file, or something like that.

The array in the first case is there for if you have more than one value.
e.i.:   const static int[] store = [-3,5,7,26,1024,1022];

<code>
import std.stdio;
void main()
{        // works for more than one value
     const static int[] store = [1024*1024];

         // get a value
     int* i = store[0..1].dup.ptr;
     writef(*i,\n);

         // change it
     *i = 4;
     writef(*i,\n);

         // original is unchanged
     i = store[0..1].dup.ptr;
     writef(*i,\n);

     int j;
     j= 1024*1024;

		// non const values anyone??
     i = (&j)[0..1].dup.ptr;

          // change it (again)
     *i = 4;
     writef(*i,\n);

         // original is unchanged
     writef(j,\n);
}
</code>