digitalmars.D.learn - opEquals default behaviour - poorly documented or am I missing
- MichaelZ (26/26) Nov 17 2015 In http://dlang.org/operatoroverloading.html#eqcmp it is stated
- =?UTF-8?Q?Ali_=c3=87ehreli?= (13/17) Nov 17 2015 Correct. The behavior for class objects is the following algorithm on
- user123ABCabc (8/9) Nov 17 2015 Wow this is terrible to compare two objects in D. The line I
- Steven Schveighoffer (4/8) Nov 17 2015 No, those are immutable stored in the data segment. Fetching them costs
- Jonathan M Davis via Digitalmars-d-learn (10/19) Nov 19 2015 Really? I would have expected caring about reference equality to be the
- MichaelZ (5/25) Nov 18 2015 Sure, but that defers to the a.opEquals / b.opEquals in many the
In http://dlang.org/operatoroverloading.html#eqcmp it is stated that "If opEquals is not specified, the compiler provides a default version that does member-wise comparison." However, doesn't this only apply to structs, and not objects? The default behaviour of opEquals for objects seems to be "is". A few paragraphs later, in http://dlang.org/operatoroverloading.html#compare, the description of the default version is repeated: "" If overriding Object.opCmp() for classes, the class member function signature should look like: ... If structs declare an opCmp member function, it should have the following form: ... Note that opCmp is only used for the inequality operators; expressions like a == b always uses opEquals. **If opCmp is defined but opEquals isn't, the compiler will supply a default version of opEquals that performs member-wise comparison.** "" Even here, the fact that the described default opEquals behaviour appears to only apply to structs is far from clear. Or am I missing something that should be obvious? Thanks, -- MichaelZ
Nov 17 2015
On 11/17/2015 12:40 AM, MichaelZ wrote:In http://dlang.org/operatoroverloading.html#eqcmp it is stated that "If opEquals is not specified, the compiler provides a default version that does member-wise comparison." However, doesn't this only apply to structs, and not objects?Correct. The behavior for class objects is the following algorithm on the same page: http://dlang.org/operatoroverloading.html#equals This one: bool opEquals(Object a, Object b) { if (a is b) return true; if (a is null || b is null) return false; if (typeid(a) == typeid(b)) return a.opEquals(b); return a.opEquals(b) && b.opEquals(a); } Ali
Nov 17 2015
On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:if (typeid(a) == typeid(b)) return a.opEquals(b);Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ? But usually when comparing objects one rather cares about the reference itself, so a comparison of the two heap addresses is enough in this case. (meaning same or not same instance, regardless of the their members values).
Nov 17 2015
On 11/17/15 3:25 PM, user123ABCabc wrote:On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:No, those are immutable stored in the data segment. Fetching them costs only doing the fetch of the class info pointer. -Steveif (typeid(a) == typeid(b)) return a.opEquals(b);Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ?
Nov 17 2015
On Tuesday, November 17, 2015 20:25:30 user123ABCabc via Digitalmars-d-learn wrote:On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:No. As Steven points out. No allocation takes place.if (typeid(a) == typeid(b)) return a.opEquals(b);Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ?But usually when comparing objects one rather cares about the reference itself, so a comparison of the two heap addresses is enough in this case. (meaning same or not same instance, regardless of the their members values).Really? I would have expected caring about reference equality to be the _rare_ case rather than the common one. And if that's what you want, == isn't the right operator to use anyway. That's what the is operator is for. Regardless, as the code posted by Ali indicates, the free function opEquals that gets called by == for classes does check whether they're the same object first by using the is operator, so all of the other checking is only done if they're not the same object. - Jonathan M Davis
Nov 19 2015
On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:On 11/17/2015 12:40 AM, MichaelZ wrote:Sure, but that defers to the a.opEquals / b.opEquals in many the interesting cases :) Which comes back to the original point: that I feel the documentation I quoted is at least easily misunderstood, if not straight out wrong.In http://dlang.org/operatoroverloading.html#eqcmp it isstated that"If opEquals is not specified, the compiler provides adefault versionthat does member-wise comparison." However, doesn't this only apply to structs, and not objects?Correct. The behavior for class objects is the following algorithm on the same page: http://dlang.org/operatoroverloading.html#equals This one: bool opEquals(Object a, Object b) { if (a is b) return true; if (a is null || b is null) return false; if (typeid(a) == typeid(b)) return a.opEquals(b); return a.opEquals(b) && b.opEquals(a); }
Nov 18 2015