Holes in structs and opEquals

Don nospam at nospam.com
Mon Mar 8 08:22:05 PST 2010


Walter Bright wrote:
> Fawzi Mohamed wrote:
>> one could argue that the unsafe operation is memset.
> 
> That's right.
> 
> 
>> The compiler always initializes a struct, so that what you describe 
>> should never happen in a safe program.
> 
> Right.
> 
> 
>> 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.
> 
> No, it's not a bug in the language, it's a bug in the user code. Using 
> =void is an advanced feature, and it requires the user to know what he's 
> doing with it. That's why it isn't allowed in safe mode.
> 
> 
>> Still I agree that traking down a bug due to this might be very ugly...
> 
> The idea with =void initializations is that they are findable using 
> grep, and so can be singled out for special attention when there is a 
> problem.

The same issue can arise with unions. This one is pretty hard to grep for:

-----------
struct S { // 16 bytes, with a hole
     ushort s;
     double d;
}

union U {
   char [16] c;
   S s;
}

void main() {
     U u;
     u.c[]='2';

     S a = S(5, 2.0);

     u.s.s = a.s;
     u.s.d = a.d;
     S b = u.s;
     assert( a == b);
}



More information about the Digitalmars-d mailing list