March 08, 2010
Walter Bright:
> It can, but I don't agree that it should. For an =void initialization, it's the user's responsibility to initialize it properly. The use of =void implies the user knows what he's doing with it, and will take care to initialize the 'holes' as necessary.

I don't fully like this design strategy, I don't like to separate so much the safe code from the unsafe code where the compiler refuses to give any safety. A good compiler has to help assure safety every time it can.

On the other hand I agree with you that your design strategy helps keep the compiler simpler (and sometimes compilation time low), and I agree that there are times where it's hopeless to try to turn something unsafe in something a little safer. It's a waste of time that can be used for something more useful. So in the end I shut up the muzzle :-)


> Trying to disable == for such structs is a losing battle, anyway, as the compiler could only detect the most obvious cases. Pass a reference to it to a function, store it in a data structure, etc., and all that goes away.

In theory a lint for D code can partially trace such movements to spot such troubles (in debug release it can even add to the void structs an extra bool attribute that always gets initialized, to tell apart initialized from uninitialized structs at runtime and spot such bugs, but this starts to sound a little silly).

Bye,
bearophile
March 08, 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);
}
1 2
Next ›   Last »