View mode: basic / threaded / horizontal-split · Log in · Help
April 19, 2012
Re: Cast Object - get null
And which version do you use? I use DMD 2.059 on Windows 7.

I get this compile error with your code
object.Error: Access Violation
----------------
41943C
4192C7
40F75B
40BE90
40BECA
40BAEB
4206E1

If i comment out this part

    if (vs2 == vf) {
        writeln("equal");
    }


it works fine.
April 19, 2012
Re: Cast Object - get null
On Thursday, April 19, 2012 10:48:45 Namespace wrote:
> And which version do you use? I use DMD 2.059 on Windows 7.
> 
> I get this compile error with your code
> object.Error: Access Violation
> ----------------
> 41943C
> 4192C7
> 40F75B
> 40BE90
> 40BECA
> 40BAEB
> 4206E1
> 
> If i comment out this part
> 
>      if (vs2 == vf) {
>          writeln("equal");
>      }
> 
> 
> it works fine.

I tried both 2.058 and the latest from github. But I'm on 64-bit Linux, so 
it's possible that you're seeing a Windows-specific issue.

- Jonathan M Davis
April 19, 2012
Re: Cast Object - get null
On Thursday, 19 April 2012 at 09:05:13 UTC, Jonathan M Davis 
wrote:
> On Thursday, April 19, 2012 10:48:45 Namespace wrote:
>> And which version do you use? I use DMD 2.059 on Windows 7.
>> 
>> I get this compile error with your code
>> object.Error: Access Violation
>> ----------------
>> 41943C
>> 4192C7
>> 40F75B
>> 40BE90
>> 40BECA
>> 40BAEB
>> 4206E1
>> 
>> If i comment out this part
>> 
>>      if (vs2 == vf) {
>>          writeln("equal");
>>      }
>> 
>> 
>> it works fine.
>
> I tried both 2.058 and the latest from github. But I'm on 
> 64-bit Linux, so
> it's possible that you're seeing a Windows-specific issue.
>
> - Jonathan M Davis

A specific Windows bug with opEquals and opCast? My Windows is 64 
bit also.
Can anyone reproduce this behaviour with Windows?
I will download dmd later again to check if i have an older 
version or beta.
April 19, 2012
Re: Cast Object - get null
> I will download dmd later again to check if i have an older 
> version or beta.

After download dmd again it get still the same compile error.
April 19, 2012
Re: Cast Object - get null
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
April 19, 2012
Re: Cast Object - get null
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.
April 19, 2012
Re: Cast Object - get null
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
April 19, 2012
Re: Cast Object - get null
A great thanks to you. But any of my tries to make
"const Vector2D vec = castFromObject(o);" possible i get an 
error. Didn't i must only write "private static const(Vector2D) 
castFromObject(Object o)" instead of "private static Vector2D 
castFromObject(Object o)"?
April 19, 2012
Re: Cast Object - get null
It seems that i can't cast if i want a const Vector2D, neither 
with castFromtObject nor with opCast. If i do it i get a very 
long list of compile errors. It's no problem because i can deal 
without cast to const but it would be usefull if you can show me 
how i can use both, const and normal casts.
April 19, 2012
Re: Cast Object - get null
On Thursday, 19 April 2012 at 15:48:29 UTC, Namespace wrote:
> It seems that i can't cast if i want a const Vector2D, neither 
> with castFromtObject nor with opCast. If i do it i get a very 
> long list of compile errors. It's no problem because i can deal 
> without cast to const but it would be usefull if you can show 
> me how i can use both, const and normal casts.

For example in this case

void foo(T)(const Vector2D!(T) vec) {
	bar(cast(Vector2s) vec);
}

void bar(const Vector2s vec) {

}

const Vector2f vf = Vector2f(23, 42);

Vector2s vs = Vector2s(vf);
Vector2s vs_ = cast(Vector2s) vf;

Vector2f vf_ = cast(Vector2f) vs;

Vector2s vs2 = Vector2s(23, 42);

if (vs2 == vf) {
	writeln("equal!");
}

foo(vf);
foo(vs);

i get this compiler errors:

cast.d(323): Error: template 
cast.Vector2D!(short).Vector2D.opCast matches more
than one template declaration, cast.d(285):opCast(U) if 
(is(Unqual!(U) == Vector
2D!(byte)) || is(Unqual!(U) == Vector2D!(ubyte)) || is(Unqual!(U) 
== Vector2D!(s
hort)) || is(Unqual!(U) == Vector2D!(ushort)) || is(Unqual!(U) == 
Vector2D!(int)
) || is(Unqual!(U) == Vector2D!(uint)) || is(Unqual!(U) == 
Vector2D!(long)) || i
s(Unqual!(U) == Vector2D!(ulong)) || is(Unqual!(U) == 
Vector2D!(float)) || is(Un
qual!(U) == Vector2D!(double)) || is(Unqual!(U) == 
Vector2D!(real))) and cast.d(
306):opCast(T) if 
(isImplicitlyConvertible!(typeof(this),const(T)))
cast.d(360): Error: template instance cast.foo!(short) error 
instantiating

I can avoid them if i change bar to

void foo(T)(const Vector2D!(T) vec) {
	static if (is(typeof(vec.x) == const float)) {
		bar(cast(Vector2s) vec);
	} else {
		bar(vec);
	}
}

Of course i must check for more then only "const float" but it is 
only a test case.
So it seems i have to change the cast operator. But i have no 
idea how.
I thougth that "inout" would help me, but i was wrong. So maybe 
you have some ideas?
1 2 3 4
Top | Discussion index | About this forum | D home