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