how to make '==' safe for classes?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Oct 28 18:42:01 UTC 2018


On Sunday, October 28, 2018 12:17:41 PM MDT Neia Neutuladh via Digitalmars-
d-learn wrote:
> On Sun, 28 Oct 2018 18:00:06 +0000, Stanislav Blinov wrote:
> > On Sunday, 28 October 2018 at 12:38:12 UTC, ikod wrote:
> >> and object.opEquals(a,b) do not inherits safety from class C
> >> properties, and also I can't override it.
> >
> > Yep. Since Object is the base class and it defines opEquals as:
> > ```
> > bool opEquals(Object);
> > ```
> >
> > the compiler rewrites `a == b` as
> > `(cast(Object)a).opEquals(cast(Object)ob)`, i.e. it inserts a @system
> > call into your code.
>
> More pedantically, it rewrites it as:
>
>   (a is b) ||
>   (a !is null && (cast(Object)a).opEquals(cast(Object)b))
>
> An object might not be equal to itself via opEquals, but it will always
> compare equal to itself with ==.

Technically, it calls the free function opEquals in object.d, which does
more than that (including introduce a hack to work around the type system to
allow comparing const objects). Specifically, the current implementation is

bool opEquals(Object lhs, Object rhs)
{
    // If aliased to the same object or both null => equal
    if (lhs is rhs) return true;

    // If either is null => non-equal
    if (lhs is null || rhs is null) return false;

    // If same exact type => one call to method opEquals
    if (typeid(lhs) is typeid(rhs) ||
        !__ctfe && typeid(lhs).opEquals(typeid(rhs)))
            /* CTFE doesn't like typeid much. 'is' works, but opEquals 
doesn't
            (issue 7147). But CTFE also guarantees that equal TypeInfos are
            always identical. So, no opEquals needed during CTFE. */
    {
        return lhs.opEquals(rhs);
    }

    // General case => symmetric calls to method opEquals
    return lhs.opEquals(rhs) && rhs.opEquals(lhs);
}

/************************
* Returns true if lhs and rhs are equal.
*/
bool opEquals(const Object lhs, const Object rhs)
{
    // A hack for the moment.
    return opEquals(cast()lhs, cast()rhs);
}

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list