dlang.org icon indicating copy to clipboard operation
dlang.org copied to clipboard

Spec does not reference about special x functions in TypeInfo_Struct

Open dlangBugzillaToGithub opened this issue 17 years ago • 5 comments

Steven Schveighoffer (@schveiguy) reported this on 2008-12-01T10:55:50Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=2482

CC List

  • Andrei Alexandrescu (@andralex)
  • berni44 (@WalterBright)
  • Infiltrator

Description

The compiler treats certain operator overloads in structs in a special manner.  Specifically, if an opCmp, opEquals, toHash or toString function matches a specific signature, a function pointer to that function is stored in the corresponding TypeInfo_Struct for that struct.

However, if the signatures are not correct, then the function pointer is not copied.  The result is that certain builtin functions or types (or user types which use the typeinfo to get at such functions) are not calling the user-defined functions accessed through the TypeInfo_Struct members.

Nowhere in the spec does it mention this, or have a list of what those signatures should be.  Also, some of the spec's examples use the wrong signature for examples of those functions.  For instance, the opCmp example for structs:

struct Pair
{
    int a, b;
    int opCmp(Pair rhs)
    {
        if (a!=rhs.a) return a-rhs.a;
        return b-rhs.b;
    }
}

This opCmp would *not* be used to sort an array of Pair types.

I think the spec should outline the four special functions mentioned above (opCmp, opEquals, toHash, toString), and what specific signature they should be for the compiler to recognize them.  Also, the above example should be updated to reflect the correct version:

struct Pair
{
    int a, b;
    int opCmp(const Pair *rhs) const
    {
        if (a!=rhs.a) return a-rhs.a;
        return b-rhs.b;
    }
}

dlangBugzillaToGithub avatar Dec 01 '08 10:12 dlangBugzillaToGithub

lt.infiltrator commented on 2014-03-18T21:55:17Z

The docs correctly provide the signature as 'int opCmp(ref const S s) const { ... }'

http://dlang.org/operatoroverloading.html#compare

dlangBugzillaToGithub avatar Mar 18 '14 21:03 dlangBugzillaToGithub

schveiguy (@schveiguy) commented on 2014-03-19T10:35:48Z

This isn't exactly what I meant. It hints at the correct signature, but does not detail the reason for using that signature (i.e. it won't be used when calling TypeInfo.compare or TypeInfo.equals).

In addition, the opEquals documentation is not very clear at all. Only ONE form gets turned into the xopEquals function pointer.

dlangBugzillaToGithub avatar Mar 19 '14 10:03 dlangBugzillaToGithub

bugzilla (@WalterBright) commented on 2019-12-21T10:13:23Z

I'm not sure at what place in the docs you'd like to see these functions mentioned. So I was not able to decide, if this issue is still valid.

dlangBugzillaToGithub avatar Dec 21 '19 10:12 dlangBugzillaToGithub

schveiguy (@schveiguy) commented on 2019-12-21T18:57:18Z

So since this was opened (11 years ago!), the .sort property is gone. And AAs have been adjusted to require only opEquals and toHash.

Not only that but the compiler has been adjusted to complain if you define one but not the other.

See: https://dlang.org/spec/hash-map.html#using_struct_as_key

Which means if you don't use the right signature, it will complain anyway.

The only remaining thing that is an undisclosed issue is the TypeInfo methods that use these items (i.e. .getHash .compare .equals). These are affected if you define the right signature, and there will be no complaints if you don't use them in an AA.

Perhaps here: https://dlang.org/phobos/object.html#.TypeInfo

You could put notes about custom functions for the three methods on structs (classes are already required to override) and identify the "correct" signature that is guaranteed to be used. And you may want to research what DMD does, because I actually don't know the requirements.

dlangBugzillaToGithub avatar Dec 21 '19 18:12 dlangBugzillaToGithub

schveiguy (@schveiguy) commented on 2019-12-21T19:04:22Z

Actually, may be good to elaborate on the points in the AA docs.

I found that defining a toHash function without const makes it skip the function for xtoHash.

A note saying "Only the above signatures are guaranteed to work with AAs. If you change the signature in some way, it may not work"

Defining opEquals without const makes it fail to be an AA key.

dlangBugzillaToGithub avatar Dec 21 '19 19:12 dlangBugzillaToGithub