www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to initialize an array of typedef-ed type?

reply MLT <none anone.com> writes:
The fact that D has real typedef, not like the fake ones of C++ is, I think,
one of its great features.

But the fact that there is no automatic cast, together with typedef is causing
me problems.

The one I'm currently fighting with is initialization:

typedef long location ;

location a[] = [1,2,3,4] ; // doesn't work: Error: cannot implicitly convert
expression

(btw. gdc has no problem, only dmd)

is there any nice way to do that? Using  [1L,2L,3L,4L] is uglier, and still
doesn't work. The only thing that works is
location a[] = [cast(location)(1), cast(location)(2), cast(location)(3),
cast(location)(4)];

which is SOMEWHAT ugly.

So, given that typedef is one of the great features of D, are you using it?
How? Or are you usually using alias?

Thanks!
May 01 2009
parent reply MLT <none anone.com> writes:
typedef long location ;
location a[] = cast(location[])[1,2,3,4] ;

Seems to work. 
I was afraid of the mess that would happen if I cast (int *) to (long *) in C...
Can I trust it? Is that the "right way" to do it?

MLT Wrote:

 The fact that D has real typedef, not like the fake ones of C++ is, I think,
one of its great features.
 
 But the fact that there is no automatic cast, together with typedef is causing
me problems.
 
 The one I'm currently fighting with is initialization:
 
 typedef long location ;
 
 location a[] = [1,2,3,4] ; // doesn't work: Error: cannot implicitly convert
expression
 
 (btw. gdc has no problem, only dmd)
 
 is there any nice way to do that? Using  [1L,2L,3L,4L] is uglier, and still
doesn't work. The only thing that works is
 location a[] = [cast(location)(1), cast(location)(2), cast(location)(3),
cast(location)(4)];
 
 which is SOMEWHAT ugly.
 
 So, given that typedef is one of the great features of D, are you using it?
How? Or are you usually using alias?
 
 Thanks!
May 01 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, May 1, 2009 at 9:15 AM, MLT <none anone.com> wrote:
 typedef long location ;
 location a[] = cast(location[])[1,2,3,4] ;

 Seems to work.
 I was afraid of the mess that would happen if I cast (int *) to (long *) in
C...
 Can I trust it? Is that the "right way" to do it?
Have you actually run it and seen what the results are? If it works, well, use it :) (It does work, and that is the right way to do it.)
May 01 2009
parent reply MLT <none anone.com> writes:
Jarrett Billingsley Wrote:

 On Fri, May 1, 2009 at 9:15 AM, MLT <none anone.com> wrote:
 typedef long location ;
 location a[] = cast(location[])[1,2,3,4] ;

 Seems to work.
 I was afraid of the mess that would happen if I cast (int *) to (long *) in
C...
 Can I trust it? Is that the "right way" to do it?
Have you actually run it and seen what the results are? If it works, well, use it :) (It does work, and that is the right way to do it.)
Yes, it does work! At first I thought that maybe on my machine int and long have the same length, or some such. But it works, for int, long, and short. And they do have different lengths. I tried a bit more: --- typedef long tlong ; void main() { int[] x = [1,2,3,4] ; tlong[] y = cast(tlong[])[1,2] ; // <- this works Stdout(y).newline ; y = cast(tlong[]) x ; // This doesn't Stdout(y).newline ; } --- prints out: [1, 2] [8589934593, 17179869187] The the initialization works, but casting from int[] to long[] in general doesn't.
May 01 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, May 1, 2009 at 10:07 AM, MLT <none anone.com> wrote:

 At first I thought that maybe on my machine int and long have the same le=
ngth, or some such. But it works, for int, long, and short. And they do hav= e different lengths. D's integer types are not like C's. They are fixed size and do not vary from platform to platform. See http://www.digitalmars.com/d/1.0/type.html
 I tried a bit more:
 ---
 typedef long tlong ;

 void main()
 {
 =A0 =A0 =A0 =A0int[] x =3D [1,2,3,4] ;

 =A0 =A0 =A0 =A0tlong[] y =3D cast(tlong[])[1,2] ; // <- this works

 =A0 =A0 =A0 =A0Stdout(y).newline ;

 =A0 =A0 =A0 =A0y =3D cast(tlong[]) x ; // This doesn't

 =A0 =A0 =A0 =A0Stdout(y).newline ;
 }
 ---
 prints out:
 [1, 2]
 [8589934593, 17179869187]

 The the initialization works, but casting from int[] to long[] in general=
doesn't. You're actually doing two different things there. Initialization is treated as a special case and casting it will cast each element. But array casts done at runtime will do a bit cast - that is, given your int[] [1, 2, 3, 4], when you cast it to a long[] at runtime, it takes that chunk of memory, figures out how many longs will fit in it (in this case 2), and gives you a new array reference to the same data but with a different type. Those big weird numbers are 0x00000002_00000001 and 0x00000004_00000003, respectively. Woah look at that, 1, 2, 3, 4! To make it more apparent, try casting an int[] to a byte[] or something. You'll see that it then splits up each original int into four bytes.
May 01 2009
parent reply MLT <none anone.com> writes:
Thanks! Yes - that works.

I have to be careful, though. Thus:

typedef long location ;
location x[] = (cast(location[])[1,2,3,4]).dup ;

works, but

location x[] = cast(location[])[1,2,3,4].dup ;

does not.

I guess there are really two different types of cast - which also confused me
in C++:
one is convert: please try to convert type1 to type2.
The other is cast: I know you think this is type1, but I know better, so from
now on, call it type2.

Is there an easy way to convert arrays from one type to another?
int[] a=[1,2,3,4] ;
long[] b ;

What is the easiest way to get a into b? 
b[] = a[] 
doesn't seem to work...



Jarrett Billingsley Wrote:

 On Fri, May 1, 2009 at 10:07 AM, MLT <none anone.com> wrote:
 
 At first I thought that maybe on my machine int and long have the same length,
or some such. But it works, for int, long, and short. And they do have
different lengths.
D's integer types are not like C's. They are fixed size and do not vary from platform to platform. See http://www.digitalmars.com/d/1.0/type.html
 I tried a bit more:
 ---
 typedef long tlong ;

 void main()
 {
        int[] x = [1,2,3,4] ;

        tlong[] y = cast(tlong[])[1,2] ; // <- this works

        Stdout(y).newline ;

        y = cast(tlong[]) x ; // This doesn't

        Stdout(y).newline ;
 }
 ---
 prints out:
 [1, 2]
 [8589934593, 17179869187]

 The the initialization works, but casting from int[] to long[] in general
doesn't.
You're actually doing two different things there. Initialization is treated as a special case and casting it will cast each element. But array casts done at runtime will do a bit cast - that is, given your int[] [1, 2, 3, 4], when you cast it to a long[] at runtime, it takes that chunk of memory, figures out how many longs will fit in it (in this case 2), and gives you a new array reference to the same data but with a different type. Those big weird numbers are 0x00000002_00000001 and 0x00000004_00000003, respectively. Woah look at that, 1, 2, 3, 4! To make it more apparent, try casting an int[] to a byte[] or something. You'll see that it then splits up each original int into four bytes.
May 01 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, May 1, 2009 at 11:34 AM, MLT <none anone.com> wrote:

 Is there an easy way to convert arrays from one type to another?
 int[] a=[1,2,3,4] ;
 long[] b ;
Not really. The best you can do is: b.length = a.length; foreach(i, ref v; b) v = a[i];
May 01 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 On Fri, May 1, 2009 at 11:34 AM, MLT <none anone.com> wrote:
 
 Is there an easy way to convert arrays from one type to another?
 int[] a=[1,2,3,4] ;
 long[] b ;
Not really. The best you can do is: b.length = a.length; foreach(i, ref v; b) v = a[i];
import std.conf; b = to!(long[])(a); That should work, in theory. -- Daniel
May 01 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, May 2, 2009 at 12:21 AM, Daniel Keep
<daniel.keep.lists gmail.com> wrote:

 import std.conf;
 b = to!(long[])(a);

 That should work, in theory.
In reality, it's std.conv ;) (or tango.util.Convert, with identical syntax)
May 01 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 On Sat, May 2, 2009 at 12:21 AM, Daniel Keep
 <daniel.keep.lists gmail.com> wrote:
 
 import std.conf;
 b = to!(long[])(a);

 That should work, in theory.
In reality, it's std.conv ;)
Those letters are like RIGHT NEXT to each otter! Don't judfe ne!
 (or tango.util.Convert, with identical syntax)
Never heard of it. :) -- Daniel
May 01 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, May 2, 2009 at 2:29 AM, Daniel Keep <daniel.keep.lists gmail.com> w=
rote:

 (or tango.util.Convert, with identical syntax)
Never heard of it. =A0:)
Oh, I see, that was written by the other Daniel Keep. It's easy to get you mixed up.
May 02 2009
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
MLT wrote:
<snip>
 The the initialization works, but casting from int[] to long[] in general
doesn't.
Yes, this is a known inconsistency. http://d.puremagic.com/issues/show_bug.cgi?id=2542 Why Walter thinks this is sensible, I'm not sure. Stewart.
May 01 2009