On 2010-03-07 15:09:53 +0100, bearophile <bearophileh...@lycos.com> said:
This comes from a small thread that is going on in digitalmars.D.learn.
This program asserts:
import std.c.string;
struct S { // 16 bytes, with a hole
ushort s;
double d;
}
void main() {
S s1, s2;
memset(&s1, ubyte.min, S.sizeof);
memset(&s2, ubyte.max, S.sizeof);
s1.s = s2.s = 0;
s1.d = s2.d = 0;
assert(s1 == s2);
}
But a correctly implemented opEquals (and opCmp) among structs has to
ignore the contents of the holes, because they can be filled with
anything, for example if the structs where not initialized (with =void).
A correct opEquals has to work recursively (so if the struct contains a
string, it has to control the string equality too).
And a built-in recursive opCmp/opHash for structs is about as useful as
having a correct opEquals.
A correct opEquals can be a little slower, but correctness come first.
In the uncommon situations where I really need max speed and I don't
care of correctness I can use a memcmp(&s1, &s2, S.sizeof). (And the
compiler is free to use just memcmp when a struct has no holes and
doesn't contain references, associative arrays and dynamic arrays).
Correctness of basic struct operators is not an optional feature, like
properties or even enums. If the opEquals among structs is wrong then
it's better to not have it at all.
one could argue that the unsafe operation is memset.
The compiler always initializes a struct, so that what you describe
should never happen in a safe program.
Still as you say the following example that might indeed considered a bug:
S s1=void,s2=void;
s1.s=0; s1.d=0;
s2.s=0; s2.d=0;
assert(s1 == s2);
here the assert might fail depending on the previous content of the memory.
I am not sure of what is the best solution, I am not sure that defining
a special comparison operation by default for each struct is the
correct solution (it can be quite some bloat), please note that a user
defined comparison function will not have these problems.
Still I agree that traking down a bug due to this might be very ugly...