www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1868] New: Interface pointer casts

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1868

           Summary: Interface pointer casts
           Product: D
           Version: 1.027
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: diggory.hardy gmail.com


The following code fails silently in one case and segfaults in another.
Presumably it should work, but if not it should probably be reported as an
error (the up-cast case can cause hard-to-track bugs).

The problem is when casting up/down with interface pointers as commented in the
following code. The class-inheritance based version is just there for
comparison; it works fine.



/// Casting tests.
module casts.d;

import tango.io.Stdout;

interface I {
    void method();
}
class C : I {
    void method() {
        Stdout ("C.method").newline;
    }
}

class A {
    void method() {
        Stdout ("A.method").newline;
    }
}
class B : A {
    void method() {
        Stdout ("B.method").newline;
    }
}

void main () {
    Stdout ("Interface upcasts:").newline;
    C c = new C();

    Stdout ("To I:").newline;
    I i = cast(I) c;
    i.method();                 // works as it should

    Stdout ("To I*:").newline;
    I* ip = cast(I*) &c;        // incorrect? no error/warning even with -w
    ip.method();                // fails silently


    Stdout ("Interface downcasts:").newline;
    I* ip2 = &i;
    ip2.method();               // works as expected

    Stdout ("To C:").newline;
    C c2 = cast(C) (*ip2);
    c2.method();                // works as expected

    /+ Compiles fine but segfaults when run:
    Stdout ("To C*:").newline;
    C* cp = cast(C*) ip2;
    Stdout ("cp is null: "~ ((cp is null) ? "true" : "false")).newline;
    cp.method();              // terminates with SIGSEGV - even though above
line says (cp !is null)
    +/


    // The class examples all work with no problems:
    Stdout ("Class upcasts:").newline;
    B b = new B();
    A a = cast(A) b;
    A* ap = cast(A*) &b;
    a.method();                 // calls B.method as it should
    ap.method();                // calls B.method, unlike interface example

    Stdout ("Class downcasts:").newline;
    B* bp = cast(B*) ap;
    bp.method();                // calls B.method, unlike interface example
    B b2 = cast(B) a;
    b2.method();                // calls B.method as it should
}


-- 
Feb 25 2008
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1868


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID





All pointer casts do is 'paint' a new type over the old one - no change in the
bits ever occurs. To get the correct change in the bits for up/down inheritance
casting, you have to cast the actual interface or class (which are reference
types).

This is working as designed. It's not a bug.

You'll see exactly the same behavior in C++ when you do things like:
    I* i;
    C** pc = (C**)&i;


-- 
Mar 01 2008