Issue 3789, stucts equality

bearophile bearophileHUGS at lycos.com
Mon Mar 26 04:58:54 PDT 2012


Issue 3789 is an enhancement request, I think it fixes one small but quite important problem in D design. The situation is shown by this simple code:


struct String {
    char[] data;
}
void main () {
    auto foo = String("foo".dup);
    auto bar = String("foo".dup);
    assert(bar !is foo, "structs aren't the same bit-wise");
    assert(bar == foo, "oops structs aren't equal");
}



The D Zen says D is designed to be safe on default and to perform unsafe (and faster) things on request. Not comparing the strings as strings in the following code breaks the Principle of least astonishment, so breaks that rule.

An acceptable alternative to fixing Bug 3789 is statically disallowing the equal operator (==) in such cases (or even in all cases).

D has the "is" for the situations where you want to perform bitwise comparison, for structs too. For the other situations where I use "==" among struts, I want it do the right thing, like comparing its contained strings correctly instead of arbitrarily deciding to use bitwise comparison of the sub-struct that represents the string.

There is already a patch for this, from the extra-good Kenji Hara:
https://github.com/D-Programming-Language/dmd/pull/387

Making "==" work as "is" for structs means using an operator for the purpose of the other operator, and it has caused some bugs in my code. And it will cause bugs in D code to come.


Another example, reduced/modified from a real bug in a program of mine:


import std.stdio;
struct Foo {
    int x;
    string s;
}
void main () {
    int[Foo] aa;
    aa[Foo(10, "hello")] = 1;
    string hel = "hel";
    aa[Foo(10, hel ~ "lo")] = 2;
    writeln(aa);
}


Here D defines a hashing for the Foo struct, but it uses the standard "==" to compare the struct keys. So the output is this, that I believe is what almost no one will ever want:

[Foo(10, "hello"):1, Foo(10, "hello"):2]

Bye,
bearophile


More information about the Digitalmars-d mailing list