Holes in structs and opEquals
Fawzi Mohamed
fmohamed at mac.com
Sun Mar 7 06:30:14 PST 2010
On 2010-03-07 15:09:53 +0100, bearophile <bearophileHUGS at 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...
More information about the Digitalmars-d
mailing list