Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 01, 2009 how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MLT |
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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MLT | 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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MLT | 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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MLT | 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 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MLT | 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 02, 2009 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley |
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 02, 2009 Re: how to initialize an array of typedef-ed type? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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)
|
Copyright © 1999-2021 by the D Language Foundation