On Friday, 17 May 2013 at 22:45:01 UTC, Timothee Cour wrote:
Although I agree that having a default constructor would be convenient, I think the problem is that S.init should be known at compile time by the
spec.

Maybe we could support the following syntax, with a static this instead of
this :

struct S
{
    int x=11;
    int y = void;

    static this()  // hypothetical
    {
        // x would already be initialized to int.init here
        assert(x == int.init);
        // y is left uninitialized here
       y=x*x;
    }
}

On Fri, May 17, 2013 at 2:34 PM, Andrej Mitrovic <andrej.mitrov...@gmail.com
wrote:

On 5/17/13, Walter Bright <wal...@digitalmars.com> wrote:
> I oppose this. D has a lot of nice features because of the > .init
property.
> Default constructors wreck that.

Would they? I'm thinking the process would be:

struct S
{
    int x;
    int y = void;

    this()  // hypothetical
    {
        // x would already be initialized to int.init here
        assert(x == int.init);

        // y is left uninitialized here
    }
}

Maybe that's already clear. But why is .init actually such a big
problem? If it becomes arbitrarily expensive to call .init of a
struct, well it's because it has to be - if the user really provided
an expensive default ctor. But it's entirely the user's
responsibility. So then .init can even throw, but throwing exceptions
isn't a big deal. Is there some other problem?

A custom default ctor in a struct is one of the most asked for
features. Just yesterday we spent several hours explaining to a C++ user why a default ctor doesn't work, and what .init is for. The whole conversation could have been avoided if D had support for custom default ctors for structs. This topic comes up very often in IRC and
the forums.

May be we can allow default ctor, but ensure that it can be
interpreted at compile time and initialize .init value with
ctored value?
Foo.init = Foo(); //somewhere in deep of compiler

But there is one trouble.

struct Foo
{
    int[] arr;
    this()//can be interpreted at compile time
    {
       arr = new int[3];
       arr[0] = 1;
       arr[1] = 2;
       arr[2] = 3;
    }
}

semantically, all new instances of Foo must get separate instance
of array.

Foo f1;
Foo f2;
assert(f1.arr.ptr !is f2.arr.ptr); //expects put FAILS

However, if Foo.init initialized by compiler with Foo() and f1
and f2 will be initialized with Foo.init, f1.arr and f2.arr will
be the same value.

We can also restrict creating of any mutable reference instances
in this() constructor:

struct Foo
{
    int[] arr;
    immutable int[] arr2;
    this()//can be interpreted at compile time
    {
       arr = new int[3]; //NG
       arr = [1,2,3]; //NG
       arr2 = [1,2,3]; //OK, because arr2 is immutable and all
instances of foo can contains an single array instance

    }
}

But this way is so difficult and isn't much profitable.



Reply via email to