On Sat, 24 Oct 2009 03:28:02 +0400, Denis Koroskin <[email protected]> wrote:

On Fri, 23 Oct 2009 19:40:33 +0400, Andrei Alexandrescu
<[email protected]> wrote:

Denis Koroskin wrote:
On Fri, 23 Oct 2009 18:46:47 +0400, Andrei Alexandrescu <[email protected]> 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?).

Reply via email to