Bug 1868 – Interface pointer casts

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2008-02-25T04:26:00Z
Last change time
2014-02-24T15:33:19Z
Assigned to
bugzilla
Creator
d

Comments

Comment #0 by d — 2008-02-25T04:26:19Z
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 }
Comment #1 by bugzilla — 2008-03-01T02:53:17Z
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;