View mode: basic / threaded / horizontal-split · Log in · Help
October 09, 2012
this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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
Re: this() in struct
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 =)
Top | Discussion index | About this forum | D home