Thread overview
this() in struct
Oct 09, 2012
Zhenya
Oct 09, 2012
Zhenya
Oct 09, 2012
Ali Çehreli
Oct 09, 2012
Maxim Fomin
Oct 09, 2012
Jonathan M Davis
Oct 09, 2012
Zhenya
Oct 09, 2012
Jonathan M Davis
Oct 09, 2012
Zhenya
Oct 09, 2012
Zhenya
Oct 09, 2012
H. S. Teoh
October 09, 2012
Hi!
I'm sorry,maybe this topic already was discussed,but could anybody explain me
why default constructor was disallowed in structs?
October 09, 2012
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?
October 09, 2012
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
October 09, 2012
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.
October 09, 2012
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
October 09, 2012
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?

October 09, 2012
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
October 09, 2012
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?
October 09, 2012
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
October 09, 2012
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 =)