Thread overview
[Issue 1563] New: dynamic cast is not always performed
Oct 10, 2007
d-bugmail
Oct 10, 2007
BCS
Oct 10, 2007
d-bugmail
Oct 10, 2007
BCS
Nov 08, 2007
d-bugmail
Jan 22, 2012
Walter Bright
October 10, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1563

           Summary: dynamic cast is not always performed
           Product: D
           Version: 1.022
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: davidl@126.com


class A{}
class B:A{}
class C:B{}
void main()
{
  A a = new B;
  C c = cast(C)cast(void*)a;
  c = cast(C)c;
  assert(c is null);  // assertion failure
  c = cast(C)cast(A)cast(void*)c;       // workaround
  assert(c is null);
}

the problem here is we don't distinguish the dynamic cast with the none dynamic
one.
For dynamic cast, it should always perform the check. And people should use
non-dynamic cast whenever it's possible. Only use dynamic cast only when we're
well informed it *requiring* a dynamic cast.
A warning is appreciated on this if the compiler is going to optimize the
dynamic cast away. And a corresponding option for this warning would be nice.
something like : -WCastToItself


-- 

October 10, 2007
Reply to d-bugmail@puremagic.com,

> http://d.puremagic.com/issues/show_bug.cgi?id=1563
> 
> Summary: dynamic cast is not always performed
> Product: D
> Version: 1.022
> Platform: PC
> OS/Version: Windows
> Status: NEW
> Severity: normal
> Priority: P2
> Component: DMD
> AssignedTo: bugzilla@digitalmars.com
> ReportedBy: davidl@126.com
> class A{}
> class B:A{}
> class C:B{}
> void main()
> {
> A a = new B;
> C c = cast(C)cast(void*)a;
> c = cast(C)c;
> assert(c is null);  // assertion failure
> c = cast(C)cast(A)cast(void*)c;       // workaround
> assert(c is null);
> }
>


it looks to me like the bug is that "cast(ClassType)voidPt" doesn't check the type. I think that assuming that something of type C actually is of type C should be allowed. The guards should be at the original assignment.

OTOH that makes things with unions fun.


October 10, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1563





------- Comment #2 from wbaxter@gmail.com  2007-10-09 22:02 -------
(In reply to comment #1)
> Reply to d-bugmail@puremagic.com,
> 
> > http://d.puremagic.com/issues/show_bug.cgi?id=1563
> > 
> > Summary: dynamic cast is not always performed
> > Product: D
> > Version: 1.022
> > Platform: PC
> > OS/Version: Windows
> > Status: NEW
> > Severity: normal
> > Priority: P2
> > Component: DMD
> > AssignedTo: bugzilla@digitalmars.com
> > ReportedBy: davidl@126.com
> > class A{}
> > class B:A{}
> > class C:B{}
> > void main()
> > {
> > A a = new B;
> > C c = cast(C)cast(void*)a;
> > c = cast(C)c;
> > assert(c is null);  // assertion failure
> > c = cast(C)cast(A)cast(void*)c;       // workaround
> > assert(c is null);
> > }
> >
> 
> 
> it looks to me like the bug is that "cast(ClassType)voidPt" doesn't check the type. I think that assuming that something of type C actually is of type C should be allowed. The guards should be at the original assignment.
> 
> OTOH that makes things with unions fun.

If you make cast(ClassType)voidPt check the type then D will have no way at all
to do a reinterpret_cast.  And I also agree that assuming something of type C
is actually type C should be allowed.  So I think the example is just bad code.
 If you do a reinterpret_cast then you're taking responsibility into your own
hands.

But the danger involved would definitely be more apparent if there were a more obvious construct for reinterpret casts like reinterpret_cast!(T).


-- 

October 10, 2007
Reply to  wbaxter@gmail.com

> If you make cast(ClassType)voidPt check the type then D will have no
> way at all
> to do a reinterpret_cast.  And I also agree that assuming something of
> type C
> is actually type C should be allowed.  So I think the example is just
> bad code.
> If you do a reinterpret_cast then you're taking responsibility into
> your own
> hands.
> But the danger involved would definitely be more apparent if there
> were a more obvious construct for reinterpret casts like
> reinterpret_cast!(T).
> 

is their any reson to cast somthing that isn't a C to type C? Only a few reasons some to mind and I'm not shrue any of them should be allowed

Get a call to a derived class to ack on a base class (this won't work anyway unless you can force a non v-tbl call, and I don't think you can)
Get somthing that is not an object at all to act like one (again v-tbl calls make this realy unlikely)
???

and even if reinterpret_cast is dropped, we will always have unions

template Reinterpret(R)
{
 R Cast(T)(T t)
 {
   union RT{R r;T t;}
   RT rt;
   rt.t=t;
   return rt.r;
 }
}


November 08, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1563


smjg@iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg@iname.com




------- Comment #4 from smjg@iname.com  2007-11-08 06:42 -------
(In reply to comment #3)
> is their any reson to cast somthing that isn't a C to type C? Only a few reasons some to mind and I'm not shrue any of them should be allowed

It's the well-documented method of testing an object to see if it's of a particular class.

http://www.digitalmars.com/d/expression.html#CastExpression

"In order to determine if an object o is an instance of a class B use a cast:

    if (cast(B) o)
    {
        // o is an instance of B
    }
    else
    {
        // o is not an instance of B
    }"

However, for this to work, o has to be declared as some superclass of B, not B itself.  If the variable is declared as a B, then the compiler is within its right to assume that the object is a B (or o is already null).

So it's reasonable that given
    C c;
then
    c = cast(C) c;
is a nop.  The problem is that, unless I've missed something, the behaviour of
casting a void* to class type is unspecified.


-- 

January 22, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1563



--- Comment #5 from github-bugzilla@puremagic.com 2012-01-21 21:00:12 PST ---
Commit pushed to https://github.com/D-Programming-Language/d-programming-language.org

https://github.com/D-Programming-Language/d-programming-language.org/commit/34b168fd3f88c749b749bf5dff6a792bb15d4853 fix Issue 1563 - dynamic cast is not always performed

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1563


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------