www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Initialization of nested struct fields

reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
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.
Jan 01 2015
parent reply "anonymous" <anonymous example.com> writes:
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".
Jan 01 2015
parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Friday, 2 January 2015 at 00:08:02 UTC, anonymous wrote:
 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.
Ah, I see. So the problem is that the nested struct doesn't really have a sensible default value, meaning you must initialize it explicitly in the constructor. Thanks for the clarification.
Jan 01 2015