[your code here]

Neia Neutuladh neia at ikeran.org
Wed Jan 30 01:20:33 UTC 2019


On Tue, 29 Jan 2019 23:45:58 +0000, Stefan Koch wrote:
> `is` is the same as `==` except for array and classes where it does
> pointer comparisons.
> since values like integers have no pointer identity.

`is` does bitwise comparisons for structs too, bypassing opEquals. And 
it's weird for interfaces.

Weirdness #1: the same object through different interfaces, where one 
interface inherits from the other, isn't the same as itself.

    interface A {}
    interface B: A {}
    class C : B {}
    A a = new C;
    B b = cast(B)a;
    writeln(a is b);  // false

This is because interfaces are implemented as lightweight adapter objects. 
An interface requires a specific vtable pointer. You can't just mutate an 
object's vtable pointer, so the compiler allocates a tiny adapter object 
inline with the primary object. The adapter has functions that locate the 
primary object and call the interface's functions on it.

The main other way to implement interfaces that I'm aware of is to pass a 
tuple of (object pointer, vtable) instead of a single pointer.

Compiling `a is b` down to `cast(Object)a is cast(Object)b` when the 
operands are interfaces would make this code work as one might naively 
expect.

Submitted https://issues.dlang.org/show_bug.cgi?id=19633

Weirdness #2: the same object through different unrelated interfaces can't 
be compared with `is`.

    interface A {}
    interface B {}
    class C : A, B {}
    A a = new C;
    B b = cast(B)a;
    writeln(a is b); // Error: incompatible types for (a) is (b):
                     // scratch.A and scratch.B

You can only compare things with `is` if they have a common base type. The 
spec doesn't state that outright.

Submitted https://issues.dlang.org/show_bug.cgi?id=19634


More information about the Digitalmars-d mailing list