September 12, 2011
On Sun, 11 Sep 2011 18:07:41 -0700, Walter Bright wrote:

> On 9/11/2011 4:53 PM, Ali Çehreli wrote:
>> The problem is, the disabled default constructor of a *member* is making a wrapper class's constructor to be disabled as well:
> 
> Right. It's infectious. This is deliberate.
> 
>  > I think this is at least limiting and very
> likely a bug.
> 
> It's deliberate. It's likely that we can find ways to loosen things up in the future, but the idea is to screw it down tight, first, instead of allowing big holes.

It is common that types insist on some data when being constructed. Many of my C++ types cannot be default-constructed. I love the idea.

So S insists that an int must be provided during its construction. That is great.

But although one of the major tasks of C's constructor is to initialize its members, it cannot initialize an S member no matter how it tries.

I can see two workarounds, none of which I believe are undesirable:

1) Insist that C defines a non-default constructor but ignores the argument with an arbitrary type:

struct S
{
    @disable this();
    this(int x)
    {}
}

class C
{
    S s;

    this(int)
    {
        this.s = S(42); // Always 42; ignores the arg
    }
}

void main()
{
    auto c = new C(0); // Unused 0
}

2) Use a pointer:

class C
{
    S * s;    // Expensive in space

    this()
    {
        this.s = new S(42);  // Expensive in time
    }
}

void main()
{
    auto c = new C;
}

Ali
September 12, 2011
On Mon, 12 Sep 2011 04:11:42 +0000, Ali Çehreli wrote:

> I can see two workarounds, none of which I believe are undesirable:

Really? I meant they are NOT desirable. :)

Ali
September 12, 2011
On 09/11/2011 08:57 PM, Walter Bright wrote:
> On 9/11/2011 9:08 AM, Max Samukha wrote:
>> This test case
>>
>> struct S
>> {
>> @disable this();
>> this(int x)
>> {
>> }
>> }
>>
>> class C
>> {
>> S s;
>> this()
>> {
>> s = S(42);
>> }
>> }
>>
>> void main()
>> {
>> auto c = new C;
>> }
>>
>> yields Error: default construction is disabled for type C
>>
>> Is it a bug?
>
> No, it's a feature!

That's sad. The question should rather have been: what do I do to use member structs that have default constructors disabled? Initially I thought that the compiler would treat the first assignment in the constructor specially as initializer. The error message "Error: constructor test.C.this field s must be initialized in constructor" suggested that. I was wrong.

So you completely disallowed runtime initialization of globals and members that have default constructors disabled? To me it looks like another feature that is a simple solution unusable in practice.

September 12, 2011
On 09/12/2011 04:07 AM, Walter Bright wrote:
> On 9/11/2011 4:53 PM, Ali Çehreli wrote:
>> The problem is, the disabled default constructor of a *member* is making
>> a wrapper class's constructor to be disabled as well:
>
> Right. It's infectious. This is deliberate.
>
>  > I think this is at least limiting and very
> likely a bug.
>
> It's deliberate. It's likely that we can find ways to loosen things up
> in the future, but the idea is to screw it down tight, first, instead of
> allowing big holes.

But how we can find the holes if we cannot even try things because they are screwed down tight? I think the right approach would be to loosen things up (without declaring them a complete feature, "resounding success", etc.), identify the holes and *then* seal the holes if possible or discard the whole idea as infeasible.
September 12, 2011
On 09/12/2011 09:38 AM, Max Samukha wrote:
> On 09/11/2011 08:57 PM, Walter Bright wrote:
>> On 9/11/2011 9:08 AM, Max Samukha wrote:
>>> This test case
>>>
>>> struct S
>>> {
>>> @disable this();
>>> this(int x)
>>> {
>>> }
>>> }
>>>
>>> class C
>>> {
>>> S s;
>>> this()
>>> {
>>> s = S(42);
>>> }
>>> }
>>>
>>> void main()
>>> {
>>> auto c = new C;
>>> }
>>>
>>> yields Error: default construction is disabled for type C
>>>
>>> Is it a bug?
>>
>> No, it's a feature!
>
> That's sad. The question should rather have been: what do I do to use
> member structs that have default constructors disabled? Initially I
> thought that the compiler would treat the first assignment in the
> constructor specially as initializer. The error message "Error:
> constructor test.C.this field s must be initialized in constructor"
> suggested that. I was wrong.
>

You were right, it does. You just cannot default construct C if S cannot be default constructed. This works:

struct S {
    @disable this();
    this(int x) {
    }
}

class C {
    S s;
    this(int) {
	s = S(42); // comment out this line and it does not compile
    }
}

void main() {
    auto c = new C(0);
}

And that implies that the 'feature' of infectious default constructor disabling for classes is worthless. But it makes perfect sense for structs.

September 12, 2011
On Sun, 11 Sep 2011 19:57:12 +0200, Walter Bright <newshound2@digitalmars.com> wrote:

> On 9/11/2011 9:08 AM, Max Samukha wrote:
>> This test case
>>
>> struct S
>> {
>> @disable this();
>> this(int x)
>> {
>> }
>> }
>>
>> class C
>> {
>> S s;
>> this()
>> {
>> s = S(42);
>> }
>> }
>>
>> void main()
>> {
>> auto c = new C;
>> }
>>
>> yields Error: default construction is disabled for type C
>>
>> Is it a bug?
>
> No, it's a feature!

Surely this must be a mistake. A class's constructor is always called when it
is created, and for non-default constructors, an uninitialized value with
@disable this() is detected. There *needs* to be a way to re-enable default
construction for classes containing structs with disabled default
constructors.

If this is simply something that is not yet done, that's fine.

-- 
  Simen
September 12, 2011
On Sun, 11 Sep 2011 13:57:12 -0400, Walter Bright <newshound2@digitalmars.com> wrote:

> On 9/11/2011 9:08 AM, Max Samukha wrote:
>> This test case
>>
>> struct S
>> {
>> @disable this();
>> this(int x)
>> {
>> }
>> }
>>
>> class C
>> {
>> S s;
>> this()
>> {
>> s = S(42);
>> }
>> }
>>
>> void main()
>> {
>> auto c = new C;
>> }
>>
>> yields Error: default construction is disabled for type C
>>
>> Is it a bug?
>
> No, it's a feature!

While I agree a nested "@disable this" struct inside a struct should disable default construction of the outer struct, a class *requires* initialization, and a default constructor is called explicitly (and can be defined!)  We are talking two different worlds here.

I think the above should be accepted.  I'm not sure how feasible it is, since it requires code path analysis.

-Steve
September 12, 2011
On Mon, 12 Sep 2011 16:43:36 +0200, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> While I agree a nested "@disable this" struct inside a struct should disable default construction of the outer struct, a class *requires* initialization, and a default constructor is called explicitly (and can be defined!)  We are talking two different worlds here.
>
> I think the above should be accepted.  I'm not sure how feasible it is, since it requires code path analysis.

What do you mean analysis? What's needed is checking 'did this class
explicitly implement a default ctor?'. Te other test ('is the struct
properly initialized?' is already performed for other constructors,
so should pose no huge impediment.

-- 
  Simen
September 12, 2011
On Mon, 12 Sep 2011 10:50:49 -0400, Simen Kjaeraas <simen.kjaras@gmail.com> wrote:

> On Mon, 12 Sep 2011 16:43:36 +0200, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> While I agree a nested "@disable this" struct inside a struct should disable default construction of the outer struct, a class *requires* initialization, and a default constructor is called explicitly (and can be defined!)  We are talking two different worlds here.
>>
>> I think the above should be accepted.  I'm not sure how feasible it is, since it requires code path analysis.
>
> What do you mean analysis? What's needed is checking 'did this class
> explicitly implement a default ctor?'. Te other test ('is the struct
> properly initialized?' is already performed for other constructors,
> so should pose no huge impediment.

I mean the compiler has to verify a constructor is called for the member struct in the class constructor.

You also must define a constructor of some kind (does not have to be a no-arg ctor), because the compiler generated default constructor cannot call the default constructor of the struct.

Maybe it's easy, but I have no idea, hence "I'm not sure" :)

-Steve
September 12, 2011
On 09/12/2011 05:10 PM, Steven Schveighoffer wrote:
> On Mon, 12 Sep 2011 10:50:49 -0400, Simen Kjaeraas
> <simen.kjaras@gmail.com> wrote:
>
>> On Mon, 12 Sep 2011 16:43:36 +0200, Steven Schveighoffer
>> <schveiguy@yahoo.com> wrote:
>>
>>> While I agree a nested "@disable this" struct inside a struct should
>>> disable default construction of the outer struct, a class *requires*
>>> initialization, and a default constructor is called explicitly (and
>>> can be defined!) We are talking two different worlds here.
>>>
>>> I think the above should be accepted. I'm not sure how feasible it
>>> is, since it requires code path analysis.
>>
>> What do you mean analysis? What's needed is checking 'did this class
>> explicitly implement a default ctor?'. Te other test ('is the struct
>> properly initialized?' is already performed for other constructors,
>> so should pose no huge impediment.
>
> I mean the compiler has to verify a constructor is called for the member
> struct in the class constructor.
>
> You also must define a constructor of some kind (does not have to be a
> no-arg ctor), because the compiler generated default constructor cannot
> call the default constructor of the struct.
>
> Maybe it's easy, but I have no idea, hence "I'm not sure" :)
>
> -Steve

The compiler already checks that for non-default class constructors, so the change would probably be very easy to carry out.