Initialization of nested struct fields

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jan 1 16:08:01 PST 2015


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".


More information about the Digitalmars-d-learn mailing list