Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

Igor Stepanov wazar.leollone at yahoo.com
Fri May 17 16:07:12 PDT 2013


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.mitrovich at gmail.com
>> wrote:
>
>> On 5/17/13, Walter Bright <walter at 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.





More information about the Digitalmars-d mailing list