www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - struct and default constructor

reply deadalnix <deadalnix gmail.com> writes:
Hi,

I wonder why struct can't have a default constructor. TDPL state that it 
is required to allow every types to have a constant .init .

That is true, however not suffiscient. A struct can has a void[constant] 
as a member and this doesn't have a .init . So this limitation does not 
ensure that the benefit claimed is garanteed.

Additionnaly, if it is the only benefit, this is pretty thin compared to 
the drawback of not having a default constructor.

We already have  disable this(); for structs. This cause the struct to 
behave differently and cause the error  initializer required for type 
xxx  when a variable of type xxx is defined without initialization. 
This doesn't prevent the struct to get a constant .init and to use it 
(even if this .init is probably garbage in this case, the whole point of 
the  disable is to force the user to use a constructor or to copy).

The whole stuff seems very unclear and limitations arbitrary.

Note that a static opCall and a  disabel default constructor doesn't do 
the trick as opCall can't be used with new to allocate on the heap. This 
is only a cheap workaround.

Note also that xxx myvar = xxx.init; worls and doesn't trigger postblit. 
So the  disable this(); is also a structure thatd oesn't garantee anything.

The point of classes and struct beeing different in D is slicing. 
Default constructor is unrelated to that problem.

Why not allow both  disable this(); and default constructor construct, 
both triggering the error  initializer required for type xxx  ? This 
would make much more sense. Postblit should also be triggered on 
assiagnation with .init to ensure the consistency of the whole construct.
Nov 27 2011
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
In addition, here is a workaround :

// Wonderfull !
 disable this();

// Default constructor workaround.
this(int dummy = 0) { ... }

But that look very dirty and it feels like working against the language.
Nov 27 2011
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Wait nevermind, I thought you mean't the ctor *actually runs*. What
you meant was disable this() doesn't work with that ctor in place.

On 11/27/11, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 That's not a workaround, that ctor never gets called unless you pass
 an argument.

Nov 27 2011
prev sibling next sibling parent deadalnix <deadalnix gmail.com> writes:
Le 27/11/2011 21:39, Andrej Mitrovic a crit :
 That's not a workaround, that ctor never gets called unless you pass
 an argument.

So if you disable this(); you shouldn't get an error. Actually, you have an implicit constructor, even if it's only to set the variable as equal to .init property of the struct.
Nov 27 2011
prev sibling next sibling parent reply =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Sun, 27 Nov 2011 21:19:38 +0100, deadalnix <deadalnix gmail.com> wrote:

 In addition, here is a workaround :

 // Wonderfull !
  disable this();

 // Default constructor workaround.
 this(int dummy = 0) { ... }

 But that look very dirty and it feels like working against the language.

I believe your "workaround" will disappoint you, as it simply does not run. import std.stdio; struct A { int value; disable this(); this(int dummy = 0) { value = 3; writeln("Hello from struct default constructor!"); // Never happens. } } void main() { A a = A(); writeln( a.value ); // Writes 0 } More importantly, this shows a bug in DMD - namely that structs with disabled default constructors can be created without a call to any constructor and with no error message. In fact, if one removes the constructor with dummy arguments, the program still compiles. http://d.puremagic.com/issues/show_bug.cgi?id=7021
Nov 27 2011
parent deadalnix <deadalnix gmail.com> writes:
Le 27/11/2011 22:24, Simen Kjærås a écrit :
 On Sun, 27 Nov 2011 21:19:38 +0100, deadalnix <deadalnix gmail.com> wrote:

 In addition, here is a workaround :

 // Wonderfull !
  disable this();

 // Default constructor workaround.
 this(int dummy = 0) { ... }

 But that look very dirty and it feels like working against the language.

I believe your "workaround" will disappoint you, as it simply does not run. import std.stdio; struct A { int value; disable this(); this(int dummy = 0) { value = 3; writeln("Hello from struct default constructor!"); // Never happens. } } void main() { A a = A(); writeln( a.value ); // Writes 0 } More importantly, this shows a bug in DMD - namely that structs with disabled default constructors can be created without a call to any constructor and with no error message. In fact, if one removes the constructor with dummy arguments, the program still compiles. http://d.puremagic.com/issues/show_bug.cgi?id=7021

So that is even worse that what I though. This struct situation is very messy and inconsistent. We should definie what we want for that and have a descent spec. I just found something new : if you disable this(this), then opAssign should be allowed (it is allowed, according to the website, when implicit cast doesn't exists). The copy don't work with opAssign and disabled postblit . . .
Nov 27 2011
prev sibling parent Steve Teale <steve.teale britseyeview.com> writes:
On Sun, 27 Nov 2011 21:39:05 +0100, Andrej Mitrovic wrote:

 That's not a workaround, that ctor never gets called unless you pass an
 argument.

But it lets you pass a Range test.
Nov 28 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
That's not a workaround, that ctor never gets called unless you pass
an argument.
Nov 27 2011