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

Timon Gehr timon.gehr at gmx.ch
Wed Oct 10 04:27:12 PDT 2012


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. (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'.


> 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?

> 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{...}
}

> 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? Not being able to have a
field of a local struct type is a serious limitation. eg:

struct Delay(T){ // where 'T' could easily be a struct from eg.
                  // std.algorithm which is instantiated locally.
     T delegate() dg;
     T value;     // ???
     // invariant !dg ==> value.__context
     ref T compute(){
         if(dg){ value = dg(); dg = null; }
         return value;
     }
     alias compute this;
}
auto delay(T)(T delegate() dg){ return Delay!T(dg); }


(Built-in nullable types would solve the issue of course.)


More information about the Digitalmars-d mailing list