www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bizarre way to 'new' arrays

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
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. 
Jun 15 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
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
Jun 15 2006
next sibling parent reply Gregor Richards <Richards codu.org> writes:
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
Jun 15 2006
parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
 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.
Jun 16 2006
parent Gregor Richards <Richards codu.org> writes:
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
Jun 16 2006
prev sibling parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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 +/
Jun 16 2006
parent reply BCS <BCS pathlink.com> writes:
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); }
Jun 16 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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
Jun 16 2006
parent BCS <BCS pathlink.com> writes:
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>
Jun 16 2006
prev sibling parent James Dunne <james.jdunne gmail.com> writes:
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
Jun 16 2006