Thread overview | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 27, 2011 struct and default constructor | ||||
---|---|---|---|---|
| ||||
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. |
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | 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. |
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | That's not a workaround, that ctor never gets called unless you pass an argument. |
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
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.
>
|
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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.
|
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | 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 |
November 27, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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 . . .
|
November 28, 2011 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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.
|
October 10, 2014 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Sunday, 27 November 2011 at 19:50:24 UTC, deadalnix wrote:
> Hi,
>
> I wonder why struct can't have a default constructor...
I know this is an old thread, but I've run into this same problem recently and search yielded this result.
I myself have tried working around the default-constructor problem with things like
this(bool bInit = true)
- which of course doesn't get invoked with MyStruct(), even with @disable this.
This seems like a language limitation to me. I have a few templated resource management objects that rely on RAII, but sometimes there's no real use for arguments, especially if a template defines what needs to be created. But now I'm forced to both disable the default constructor AND to require unnecessary parameters. Why? Another workaround is to use some object factory mechanism, but that's just extra code to maintain.
Also, apparently doing cleanup in class object destructors is a big no-no as resources that it may need to clean up could potentially already be destroyed, depending on when the GC kicks in and what objects are cleared by it. So no possibility of using objects as resource acquire/release mechanisms.
I assume using scoped with class objects will have a similar problem..
|
October 10, 2014 Re: struct and default constructor | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid Attachments: | On Fri, 10 Oct 2014 01:32:51 +0000 dcrepid via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > This seems like a language limitation to me. that is what we have to pay for the rule "type must always has well-defined initial value". the thing is that struct must have initial value that can be calculated without executing any code. i.e. `T.init`. with default struct constructor we can't have such initial state anymore. this is highly unsafe. yet compiler ignores constructor with default args when creating struct. i.e. for this: struct A { @disable this (); this (int v=42) { ... } ... } ... auto a = A(); compiler will not call this(42), but will generate error. i'm not sure if this must be changed though, 'cause `this (int)` now becames default constructor and we have no well-defined initial value anymore. > So no possibility of using > objects as resource acquire/release mechanisms. > I assume using scoped with class objects will have a similar > problem.. no, stack-allocated object is GC root, so anything it holds reference to will not be destroyed until stack object is alive. so destructor of stack-allocated object *can* be used for doing cleanup. but you can use templates to build your "anchor" structs. it's hard to say without concrete code samples. |
Copyright © 1999-2021 by the D Language Foundation