What is the case against a struct post-blit default constructor?

Don Clugston dac at nospam.com
Wed Oct 10 04:59:38 PDT 2012


On 10/10/12 13:27, Timon Gehr wrote:
> On 10/10/2012 12:45 PM, Don Clugston wrote:
>> On 10/10/12 11:21, Jonathan M Davis wrote:
>>> On Monday, October 08, 2012 18:47:43 Malte Skarupke wrote:
>>>> So I really can't think of a reason for why you wouldn't want
>>>> this. Yet this discussion has happened several times already.
>>>> There is clear demand for it and very good reasons, such as those
>>>> mentioned in all the linked discussions.
>>>>
>>>> So why is this being rejected?
>>>
>>> It buys you pretty much nothing. There are plenty of places in the
>>> language
>>> where init is required (e.g. member variables that can't be directly
>>> initialized and the elements in an array). So, init _will_ be used
>>> regardless
>>> of what you do with the default constructor. If you want to prevent
>>> that, then
>>> you need to disable init, which we can already do. But you're not
>>> going to get
>>> those things initialized with the default constructor, which kind of
>>> defeats
>>> the purpose of the default constructor. If you can't guarantee that
>>> every
>>> instance which isn't explicitly constructed is default constructed, then
>>> what's the point?
>>
>> Of course there would be no point.
>> You have not answered the question. The issue is, WHY can we not
>> guarantee that that the struct default constructor is called?
>>
>
> Because the current language does not. :o)
>
> Because that would imply disabling .init.
>   - Which defeats the .init idiom in generic code. I am not convinced
>     that we need that though.

I don't like the .init idiom, I'm not sure it actually works. The 
semantics of .init aren't well defined. There is no guarantee that it is 
a valid value of the type.


  (T x)=>... does the job just fine, and
>     .init has issues, as eg. int.init has special implicit conversion
>     rules that not all members of the type int share.
>   - Need a new (unsafe) language feature in order to be able to
>     implement eg. 'emplace'.

Exactly.


>> I have a vague memory that Walter mentioned a technical difficulty once
>> but I don't remember anything about what it was.
>>
>> I can't imagine what it would be.
>
> +1.
>
>> Even in the worst case, it would be
>> possible to run CTFE on the default constructor in order to create
>> .init. This would limit the default constructor to things which are
>> CTFEable, but even that would still be useful for templated structs.
>>
>
> You could run CTFE on the default constructor iff .init is requested,
> but I don't really see the point. What would be the benefit?

You could have more complicated relationships between members.

struct W
{
   int x;
   int y;
}

W bar(T)() { return W(T.sizeof, T.alignof); }

struct Foo(T)
{
    int m;
    int n;
    int k;

    this() {
      W w = bar!(T)();
      m = w.x;
      n = w.y;
      k = abs(64 - m - n);
    }
}

of course it gains in value as bar!()() gets more complicated.


>> Really, there does not seem to me to be any point in having an invariant
>> for a struct, without a default constructor.
>>
>
> One can use a dented invariant.
>
> struct S{
>      bool valid = false;
>      // ...
>      invariant(){ if(valid) assert(...); }
>      void establishInvariant()out{assert(valid);}body{...}
>}

Yes, you have to do something like that. It's absolute garbage. When you 
have a hack like that, I don't see the point of having invariants in the 
language.


>> BTW .init doesn't really work for nested structs anyway. There are
>> several open bugs related to that.
>>
>
> That is true, what are the plans for that?

Don't know.


More information about the Digitalmars-d mailing list