this() not executing code on structs

Denis Koroskin 2korden at gmail.com
Fri Oct 23 18:14:18 PDT 2009


On Sat, 24 Oct 2009 03:28:02 +0400, Denis Koroskin <2korden at gmail.com>  
wrote:

> On Fri, 23 Oct 2009 19:40:33 +0400, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>
>> Denis Koroskin wrote:
>>> On Fri, 23 Oct 2009 18:46:47 +0400, Andrei Alexandrescu  
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> Don wrote:
>>>>> Bartosz Milewski wrote:
>>>>>> Andrei Alexandrescu Wrote:
>>>>>>
>>>>>>>     this() { myCount = count++; }       // ERROR
>>>>>>
>>>>>> It's worse than that. Try this:
>>>>>>
>>>>>> struct foo {
>>>>>>        this(int dummy = 0) { writeln("Default constructor");}
>>>>>> }
>>>>>>
>>>>>> foo x = foo();
>>>>>>
>>>>>> Nothing gets printed. If default constructors are disallowed, so  
>>>>>> should constructors with all parameters defaulted.
>>>>>  Ouch.
>>>>> It's because it's interpreting foo() as a struct literal.
>>>>> If a struct has any constructors, struct literals should be disabled.
>>>>
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=3438
>>>>
>>>> The more I think of it, the more imperious it becomes that we allow  
>>>> default constructors that execute code. The main question is what to  
>>>> do about .init.
>>>>
>>>> Andrei
>>>  I'd suggest ditching it and enforce explicit member initialization  
>>> (unless a variable is nullable). This will also remove a lot of bloat  
>>> from executables.
>>
>> I don't understand. The problem right now is that even of all fields  
>> are explicitly intialized, e.g.
>>
>> struct A {
>>      Widget x = null;
>>      double d = 0;
>>      int i = -1;
>> }
>>
>> there is still no ability to execute code upon initialization, e.g.  
>> force A to contain a non-null Widget.
>>
>>
>> Andrei
>
> Yes, I was talking about a different scheme, where default ctors are
> allowed. They aren't allowed now but we are talking about things we can
> change/improve, right?
>
> I mean there is no _real_ need for T.init, just malloc()'ate some memory  
> and call the __ctor on it. Struct members default values would be  
> converted into runtime initialization expressions like this:
>
> struct A
> {
>      this(Args)(Args args) // may be an empty set of arguments
>      {
>          // the following lines are inserted automatically
>          x = null;
>          d = 0;
>          i = -1;
>
>          // user-defined code follows
>          i = 42;
>      }
>
>      Widget x = null;
>      double d = 0;
>      int i = -1;
> }
>
> Optimization pass would eliminate double initialization (in the case  
> about i would be initialized straight to 42)

This scheme works fine for C++, and it would fit languages that don't  
support MI even better.

I believe D's approach with init is a bit easier to understand (rules are  
less complicated), but it is also not very efficient: a few stores/pushes  
are faster than memcpy'ing few bytes in most cases (minor but still). And  
an additional bloat it introduces is also not very welcome, of course.

While I'm not a idealizing C++ object initialization scheme, I do think it  
is sound (even though it is complicated). Some variation of it may be well  
suitable for D.

I made the following post a while ago  
(http://www.digitalmars.com/d/archives/digitalmars/D/D_programming_practices_object_construction_order_85468.html),  
it may interest you as I believe it is relevant to this discussion.  
Unfortunately no one has made any comments about it (is it silly, or just  
nobody cares?).



More information about the Digitalmars-d mailing list