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