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