Thread overview
Casts that makes no sense (!)
Mar 08, 2010
Ary Borenszweig
Mar 08, 2010
Ary Borenszweig
Mar 08, 2010
Ary Borenszweig
March 08, 2010
The following compiles:

import std.stdio;

interface I {
}

class A : I {
}

class B {
}

int main() {
  I i = new A();
  A a = cast(A) i;
  B b = cast(B) i; // shouldn't compile
  B c = cast(B) a; // shouldn't compile

  writeln(a);
  writeln(b);
  writeln(c);

  return 0;
}

But two lines there doesn't make sense:

B b = cast(B) i;

An instance of I can never be a B, so why the cast is allowed?

B c = cast(B) a;

An instance of A can never be an A, so why the cast is allowed?

I think these casts should result in an error. This can prevent some bugs.

Java and C# work like that. You can't cast an object of instance of type A to type B if both types are classes and B isn't a supertype or subtype of A.
March 08, 2010
On Mon, 08 Mar 2010 09:38:08 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:

> The following compiles:
>
> import std.stdio;
>
> interface I {
> }
>
> class A : I {
> }
>
> class B {
> }
>
> int main() {
>    I i = new A();
>    A a = cast(A) i;
>    B b = cast(B) i; // shouldn't compile
>    B c = cast(B) a; // shouldn't compile
>
>    writeln(a);
>    writeln(b);
>    writeln(c);
>
>    return 0;
> }
>
> But two lines there doesn't make sense:
>
> B b = cast(B) i;
>
> An instance of I can never be a B, so why the cast is allowed?

class C: B, I {}

I i = new C;
B b = cast(B)i; // should work

> B c = cast(B) a;
>
> An instance of A can never be an A, so why the cast is allowed?

Aside from the typo, I agree with you there, this should never be possible, because a derived class can not inherit both B and A.

> I think these casts should result in an error. This can prevent some bugs.
>
> Java and C# work like that. You can't cast an object of instance of type A to type B if both types are classes and B isn't a supertype or subtype of A.

This rule makes sense.  On the other hand, I wonder how the new ability to cast to any type works in terms of classes.  Can you define cast!(A)() in B for instance?  I suppose you could make a caveat that either the class must inherit A or define an opCast for A.

-Steve
March 08, 2010
Steven Schveighoffer wrote:
> On Mon, 08 Mar 2010 09:38:08 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:
> 
>> The following compiles:
>>
>> import std.stdio;
>>
>> interface I {
>> }
>>
>> class A : I {
>> }
>>
>> class B {
>> }
>>
>> int main() {
>>    I i = new A();
>>    A a = cast(A) i;
>>    B b = cast(B) i; // shouldn't compile
>>    B c = cast(B) a; // shouldn't compile
>>
>>    writeln(a);
>>    writeln(b);
>>    writeln(c);
>>
>>    return 0;
>> }
>>
>> But two lines there doesn't make sense:
>>
>> B b = cast(B) i;
>>
>> An instance of I can never be a B, so why the cast is allowed?
> 
> class C: B, I {}
> 
> I i = new C;
> B b = cast(B)i; // should work

Ah, good one! I just tested it in Java and it also compiles, so I was wrong.

> 
>> B c = cast(B) a;
>>
>> An instance of A can never be an A, so why the cast is allowed?
> 
> Aside from the typo, I agree with you there, this should never be possible, because a derived class can not inherit both B and A.

Where's the typo?

> 
>> I think these casts should result in an error. This can prevent some bugs.
>>
>> Java and C# work like that. You can't cast an object of instance of type A to type B if both types are classes and B isn't a supertype or subtype of A.
> 
> This rule makes sense.  On the other hand, I wonder how the new ability to cast to any type works in terms of classes.  Can you define cast!(A)() in B for instance?  I suppose you could make a caveat that either the class must inherit A or define an opCast for A.

Yes, you'd always have to also check if an opCast is present.

> 
> -Steve
March 08, 2010
On Mon, 08 Mar 2010 10:12:53 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:

> Steven Schveighoffer wrote:
>> On Mon, 08 Mar 2010 09:38:08 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:

>>> An instance of A can never be an A, so why the cast is allowed?
>>  Aside from the typo, I agree with you there, this should never be possible, because a derived class can not inherit both B and A.
>
> Where's the typo?

"An instance of A can never be an A"

Obviously you meant an instance of B :)

-Steve
March 08, 2010
Steven Schveighoffer wrote:
> On Mon, 08 Mar 2010 10:12:53 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Mon, 08 Mar 2010 09:38:08 -0500, Ary Borenszweig <ary@esperanto.org.ar> wrote:
> 
>>>> An instance of A can never be an A, so why the cast is allowed?
>>>  Aside from the typo, I agree with you there, this should never be possible, because a derived class can not inherit both B and A.
>>
>> Where's the typo?
> 
> "An instance of A can never be an A"
> 
> Obviously you meant an instance of B :)
> 
> -Steve

Aaaah... I was looking for the typo in the code