On Thursday, 1 January 2015 at 23:06:30 UTC, Peter Alexander wrote:
Can someone please explain this behaviour? I find it totally bizarre.

auto f(T)(T x) {
        struct S {
                T y;
                this(int) { }
        }
        return S(0);
}


void main() {
        f(f(0));
}

Error: constructor f376.f!(S).f.S.this field y must be initialized in constructor, because it is nested struct

Why must y be initialized in the constructor? It isn't const. Why isn't it default initialized?

Is this explained anywhere in the docs? I can't see anything in the nested struct section, or in any constructor section.

A simplification of your code that helped me understand what's going on:

auto f() {
    struct S1 {
        this(int) { }
    }
    return S1();
}

struct S2 {
typeof(f()) y; /* Error: field y must be initialized in constructor, because it is nested struct */
    this(int) { }
}

Apparently dmd thinks that the result of f must be a nested struct. I.e. it needs a context pointer. And I guess hell would break loose if you'd use a nested struct with a null context pointer. At least when the context pointer is actually used, unlike here.

If the struct needed to be nested, the compiler would maybe do the right thing here: preventing null/garbage dereferencing. As it is, it should maybe see that S1 doesn't need a context pointer.

You can explicitly mark the struct as not-nested by making it "static".

Reply via email to