Cast Object - get null
Jonathan M Davis
jmdavisProg at gmx.com
Thu Apr 19 02:51:54 PDT 2012
On Thursday, April 19, 2012 11:27:20 Namespace wrote:
> On Thursday, 19 April 2012 at 09:22:24 UTC, Jonathan M Davis
>
> wrote:
> > On Thursday, April 19, 2012 11:15:23 Namespace wrote:
> >> A specific Windows bug with opEquals and opCast?
> >
> > Maybe. Certainly, it's working on my Linux box, so if you're
> > compiling the
> > same code that I am, and you're using 2.059, it definitely
> > sounds like it's a
> > Windows-specific bug.
> >
> >> My Windows is 64 bit also.
> >
> > The fact that it's 64-bit shouldn't matter on Windows, because
> > dmd can't
> > generate 64-bit code on Windows yet.
> >
> > - Jonathan M Davis
>
> Ok. And what schould i do now? Any patches available for that?
> Otherwise i must cast up to dmd 2.060 explicit as you do in the
> first if condition.
Actually, I just re-ran the code on my box, and it does segfault. Either I
forgot to run it or I didn't notice the segfault, since it isn't as obvious on
Linux with all of the other output:
vs.x: 23, vs.y: 42
raw.Vector2D!(short).Vector2D
raw.Vector2D!(short).Vector2D
equal
raw.Vector2D!(float).Vector2D
null
Segmentation fault
What's going wrong is that this cast in opEquals:
Vector2D!(T) vec = cast(Vector2D!(T)) o;
is failing. The result is null. That's what you'd expect if the built-in cast
is being used rather than opCast. And if I put print statements in all three
of the opCasts, none of them are called.
Upon thinking further about it, I believe that the problem is that you're
casting from _Object_ rather than one of the other instantiations of Vector2D,
and Object obviously doesn't define an opCast for your type. So, it uses the
normal, built-in cast, and it fails, because the type that you're attempting
to cast to is not derived from the one that you're trying to cast to. If you
could get it to its actual type and _then_ cast it, you could do it. But
that's a rather nasty problem. After messing with it a bit though, I do
believe that I've come up with a solution. Change opEquals to this:
override bool opEquals(Object o) const {
writeln(o);
auto vec = castFromObject(o);
assert(vec !is null);
writeln(vec);
return vec.x == this.x && vec.y == this.y;
}
private static Vector2D castFromObject(Object o)
{
import std.typetuple;
foreach(U; TypeTuple!(byte, ubyte, short, ushort, int, uint,
long, ulong, float, double, real))
{
if(auto vec = cast(Vector2D!U)o)
return cast(Vector2D)vec;
}
return null;
}
I believe that that takes care of the problem.
By the way, inside of a template, you don't need to reuse the template
arguments when refering to it. So, inside of Vector2D, you can use Vector2D
instead of Vector2D!T.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list