default '==' on structs

spir denis.spir at gmail.com
Thu Feb 3 03:18:30 PST 2011


On 02/03/2011 09:09 AM, Lars T. Kyllingstad wrote:
> On Wed, 02 Feb 2011 17:35:50 +0100, spir wrote:
>
>> On 02/02/2011 04:20 PM, Lars T. Kyllingstad wrote:
>>> On Wed, 02 Feb 2011 15:55:53 +0100, spir wrote:
>>>
>>>> Hello,
>>>>
>>>> What are the default semantics for '==' on structs?
>>>>
>>>> I ask this because I was forced to write opEquals on a struct to get
>>>> expected behaviour. This struct is basically:
>>>>
>>>> struct Lexeme {
>>>>        string tag;
>>>>        string slice;
>>>>        Ordinal index;
>>>> }
>>>>
>>>> Equal Lexeme's compare unequal using default '=='. When I add:
>>>>
>>>>        const bool opEquals (ref const(Lexeme) l) {
>>>>            return (
>>>>                   this.tag   == l.tag
>>>>                &&  this.slice == l.slice
>>>>                &&  this.index == l.index
>>>>            );
>>>>        }
>>>>
>>>> then all works fine. What do I miss?
>>>
>>> I think the compiler does a bitwise comparison in this case, meaning
>>> that it compares the arrays' pointers instead of their data.  Related
>>> bug report:
>>>
>>>     http://d.puremagic.com/issues/show_bug.cgi?id=3433
>>>
>>> -Lars
>>
>> Thank you, Lars.
>> In fact, I do not really understand what you mean. But it helped me
>> think further :-)
>> Two points:
>>
>> * The issue reported is about '==' on structs not using member opEquals
>> when defined, instead performing bitwise comparison. This is not my
>> case: Lexeme members are plain strings and an uint. They should just be
>> compared as is. Bitwise comparison should just work fine. Also, this
>> issue is marked solved for dmd 2.037 (I use 2.051).
>
> Yeah, but I would say it isn't really fixed.  It seems that the final
> decision was that members which define opEquals() are compared using
> opEquals(), while all other members are compared bitwisely.  But built-in
> dynamic arrays can also be compared in two ways, using '==' (equality) or
> 'is' (identity, i.e. bitwise equality).  Struct members which are dynamic
> arrays should, IMO, be compared using '==', but apparently they are not.
>
>
>> * The following works as expected:
>>
>> struct Floats {float f1, f2;}
>> struct Strings {string s1, s2;}
>> struct Lexeme {
>>       string tag;
>>       string slice;
>>       uint index;
>> }
>>
>> unittest {
>>       assert ( Floats(1.1,2.2)  == Floats(1.1,2.2) ); assert (
>>       Strings("a","b") == Strings("a","b") ); assert ( Lexeme("a","b",1)
>>       == Lexeme("a","b",1) );
>> }
>>
>> This shows, if I'm right:
>> 1. Array (string) members are compared by value, not by ref/pointer. 2.
>> Comparing Lexeme's works in this test case.
>
> Nope, it doesn't show that, because you are assigning literals to your
> strings, and DMD is smart enough to detect duplicate literals.
>
>      string s1 = "foo";
>      string s2 = "foo";
>      assert (s1.ptr == s2.ptr);
>
> That is actually pretty cool, by the way. :)
>
> Here's an example to demonstrate my point:
>
>      import std.stdio;
>
>      struct T { string s; }
>
>      void main(string[] args)
>      {
>          auto s1 = args[1];
>          auto s2 = args[2];
>          auto t1 = T(s1);
>          auto t2 = T(s2);
>
>          if (s1 == s2) writeln("Arrays are equal");
>          else writeln("Arrays are different");
>
>          if (t1 == t2) writeln("Structs are equal");
>          else writeln("Structs are different");
>      }
>
> If run with the arguments "foo bar" it prints:
>
>      Arrays are different
>      Structs are different
>
> If run with the arguments "foo foo" it prints:
>
>      Arrays are equal
>      Structs are different
>
> -Lars

Thank you again, Lars: I was wrong and you are right. The key point is interned 
string literals, that interacted with my issue.

Denis
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d-learn mailing list