www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - this() in struct

reply "Zhenya" <zheny list.ru> writes:
Hi!
I'm sorry,maybe this topic already was discussed,but could 
anybody explain me
why default constructor was disallowed in structs?
Oct 09 2012
next sibling parent reply "Zhenya" <zheny list.ru> writes:
On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could 
 anybody explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?
Oct 09 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/09/2012 10:08 AM, Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could anybody
 explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

I am not sure about the rationale myself. This issue is being discussed at the main D forum: http://forum.dlang.org/thread/fgldbozuneoldxjrwxje forum.dlang.org Here is what I know: If the initial values are the same for all objects, then use initial values: struct S { int i = 42; double d = 1.5; } If you do not want to keep the initial values or they are not available at compile time, then you can use a 'static opCall': struct S { int i; double d; static S opCall() { S result; result.i = 43; result.d = 2.5; return result; } } void main() { auto s = S(); } But then that opCall gets in the way and you can't write the following any more: auto s = S(44, 5.5); /* Error: function deneme.S.opCall () is not callable using argument types (int,double) Error: expected 0 arguments, not 2 for non-variadic function type S() */ It still resolves to the static opCall even though the parameters don't match. Ali
Oct 09 2012
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 9 October 2012 at 17:32:35 UTC, Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could 
 anybody explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

TDPL, the book by Andrei Alexandrescu, says that it was done for having compile time known default value for structure types which is T.init in general. For classes T.init is null so there is no problem. Assumption here is that statically known T.init and default constructor cannot coexist, however there are discussion in this forum that this issue may be reconsidered. Absence of default structure constructors is a piece of the puzzle which is creation of D structures and consists of structure constructors, static/object opCall methods, struct literals together with static initialization. You may use any of this method for initialization, the problem is IMHO in their contradiction and priority.
Oct 09 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 09, 2012 19:08:35 Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could
 anybody explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

It's because of the init property. All types in D are default-initialized to their init property, and that property must be known at compile time (meaning that it doesn't work very well for it to involve a constructor). For structs, the init property is decided by what all of the member variables are directly initialized to. So, struct S { int i = 5; string s = "hello"; } assert(S.init == S(5, "hello")); S s; assert(s == S.init); This has the unfortunate result that we don't get a default constructor. The workaround is to declare a static opCall function. struct S { int i = 5; string s = "hello"; static S opCall() { return S(22, "catch"); } } S s; assert(s == S.init); S s2 = S(); auto s3 = S(); assert(s2 == S(22, "catch")); assert(s2 == s3); It doesn't make it so that the struct is default-initialized to the result of static opCall, and it doesn't guarantee that the result of static opCall is used when no constructor is called, but if you use S() explicitly, then it will be used. A solid design decision in the language (e.g. requiring that everything be default-initialized) can have the unfortunate side effect of restricting other choices, and in this case, mucks up default constructors for structs. - Jonathan M Davis
Oct 09 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
On Tuesday, 9 October 2012 at 18:29:18 UTC, Jonathan M Davis 
wrote:
 On Tuesday, October 09, 2012 19:08:35 Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could
 anybody explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

It's because of the init property. All types in D are default-initialized to their init property, and that property must be known at compile time (meaning that it doesn't work very well for it to involve a constructor). For structs, the init property is decided by what all of the member variables are directly initialized to. So, struct S { int i = 5; string s = "hello"; } assert(S.init == S(5, "hello")); S s; assert(s == S.init); This has the unfortunate result that we don't get a default constructor. The workaround is to declare a static opCall function. struct S { int i = 5; string s = "hello"; static S opCall() { return S(22, "catch"); } } S s; assert(s == S.init); S s2 = S(); auto s3 = S(); assert(s2 == S(22, "catch")); assert(s2 == s3); It doesn't make it so that the struct is default-initialized to the result of static opCall, and it doesn't guarantee that the result of static opCall is used when no constructor is called, but if you use S() explicitly, then it will be used. A solid design decision in the language (e.g. requiring that everything be default-initialized) can have the unfortunate side effect of restricting other choices, and in this case, mucks up default constructors for structs. - Jonathan M Davis

Ok.Then can I do my own .init property that can be executed in compile-time?
Oct 09 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Oct 09, 2012 at 07:08:35PM +0200, Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
Hi!
I'm sorry,maybe this topic already was discussed,but could anybody
explain me why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

Use initializers: struct S { int x = 1; int y = 2; } T -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous
Oct 09 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
On Tuesday, 9 October 2012 at 18:29:18 UTC, Jonathan M Davis 
wrote:
 On Tuesday, October 09, 2012 19:08:35 Zhenya wrote:
 On Tuesday, 9 October 2012 at 17:21:47 UTC, Zhenya wrote:
 Hi!
 I'm sorry,maybe this topic already was discussed,but could
 anybody explain me
 why default constructor was disallowed in structs?

And if I have to do some initialization of data members,what is the way to do it?

It's because of the init property. All types in D are default-initialized to their init property, and that property must be known at compile time (meaning that it doesn't work very well for it to involve a constructor). For structs, the init property is decided by what all of the member variables are directly initialized to. So, struct S { int i = 5; string s = "hello"; } assert(S.init == S(5, "hello")); S s; assert(s == S.init); This has the unfortunate result that we don't get a default constructor. The workaround is to declare a static opCall function. struct S { int i = 5; string s = "hello"; static S opCall() { return S(22, "catch"); } } S s; assert(s == S.init); S s2 = S(); auto s3 = S(); assert(s2 == S(22, "catch")); assert(s2 == s3); It doesn't make it so that the struct is default-initialized to the result of static opCall, and it doesn't guarantee that the result of static opCall is used when no constructor is called, but if you use S() explicitly, then it will be used. A solid design decision in the language (e.g. requiring that everything be default-initialized) can have the unfortunate side effect of restricting other choices, and in this case, mucks up default constructors for structs. - Jonathan M Davis

Ok.Then,can I do my own .init property,that can be executed in compile time?
Oct 09 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 09, 2012 20:09:56 Zhenya wrote:
 Ok.Then can I do my own .init property that can be executed in
 compile-time?

No. You directly initialize the member variables to what you want them to be, and that's the values that they have in the init property. You can't have anything like a function or constructor to initialize them all together. However, you _can_ use the results of functions to initialize the member variables if the functions will work at compile time. e.g. struct S { int i = foo(); string s = bar("joe"); } int foo() { return 7; } string bar(string str) { return str ~ " schmoe"; } assert(S.init == S(7, "joe schmoe")); - Jonathan M Davis
Oct 09 2012
prev sibling parent "Zhenya" <zheny list.ru> writes:
On Tuesday, 9 October 2012 at 19:04:40 UTC, Jonathan M Davis 
wrote:
 On Tuesday, October 09, 2012 20:09:56 Zhenya wrote:
 Ok.Then can I do my own .init property that can be executed in
 compile-time?

No. You directly initialize the member variables to what you want them to be, and that's the values that they have in the init property. You can't have anything like a function or constructor to initialize them all together. However, you _can_ use the results of functions to initialize the member variables if the functions will work at compile time. e.g. struct S { int i = foo(); string s = bar("joe"); } int foo() { return 7; } string bar(string str) { return str ~ " schmoe"; } assert(S.init == S(7, "joe schmoe")); - Jonathan M Davis

Understood.Thank you very much guys =)
Oct 09 2012