Jump to page: 1 2
Thread overview
struct constructors and destructors.
Jul 19, 2017
Danni Coy
Jul 19, 2017
Stefan Koch
Jul 19, 2017
Danni Coy
Jul 19, 2017
Stefan Koch
Jul 19, 2017
Adam D. Ruppe
Jul 19, 2017
Danni Coy
Jul 19, 2017
SrMordred
Jul 19, 2017
SrMordred
Jul 20, 2017
Danni Coy
Jul 20, 2017
Adam D. Ruppe
Jul 19, 2017
Adam D. Ruppe
July 19, 2017
Is there a reason that the following code

struct Foo
{
    this (string name)
    { do_something(name); }

    ~this()
    { undo_something(); }
}

Foo foo = void;

void open()
{
    foo = Foo("test"); // <- this line
}

tries to OpAssign foo to itself then calls foo's destructor?


July 19, 2017
On Wednesday, 19 July 2017 at 07:48:28 UTC, Danni Coy wrote:
> Is there a reason that the following code
>
> struct Foo
> {
>     this (string name)
>     { do_something(name); }
>
>     ~this()
>     { undo_something(); }
> }
>
> Foo foo = void;
>
> void open()
> {
>     foo = Foo("test"); // <- this line
> }
>
> tries to OpAssign foo to itself then calls foo's destructor?

What happens is this.

void open()
{
  foo = () {
  Foo _tmp = Foo.__ctor("test");
  return _tmp;
  } ();
}


July 19, 2017
On Wed, Jul 19, 2017 at 7:09 PM, Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

>
> What happens is this.
>
> void open()
> {
>   foo = () {
>   Foo _tmp = Foo.__ctor("test");
>   return _tmp;
>   } ();
> }
>
>
> Error: need 'this' for 'this' of type 'ref Foo(string s)'


July 19, 2017
On Wednesday, 19 July 2017 at 12:23:06 UTC, Danni Coy wrote:
> On Wed, Jul 19, 2017 at 7:09 PM, Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>>
>> What happens is this.
>>
>> void open()
>> {
>>   foo = () {
>>   Foo _tmp = Foo.__ctor("test");
>>   return _tmp;
>>   } ();
>> }
>>
>>
>> Error: need 'this' for 'this' of type 'ref Foo(string s)'

I posted pseudo code to show you that you are creating a temporary.
Which leaves the scope after assigning.
And therefore triggers the destructor.
July 19, 2017
On Wednesday, 19 July 2017 at 07:48:28 UTC, Danni Coy wrote:
> tries to OpAssign foo to itself then calls foo's destructor?

Are you sure that's what's actually happening?


What should be happening there is:

1) it calls Foo's constructor on a temporary location
2) it destroys the old contents of `foo`
3) it moves the Foo from (1) into the variable freshly destroyed from (2)


It is void initialized, so you might think there are no old contents of foo, but the compiler doesn't know this for certain (consider you called `open` twice. would be true the first time, but not the second time. the compiler needs to generate the function so it works both times).


There is a function which the compiler knows will only be called once though: a static constructor.

---
shared static this()
{
   foo = Foo("test");
}
---


That only runs once, and the compiler will skip the destruction of old `foo`.... as long as it isn't already initialized. Ironically, removing the `= void` from it causes the compiler to realize this and only use the ctor initialization. Otherwise, it tries to destroy the existing item, apparently not realizing it was void.... arguably a small compiler bug there.
July 19, 2017
On Wednesday, 19 July 2017 at 12:34:50 UTC, Stefan Koch wrote:
> Which leaves the scope after assigning.
> And therefore triggers the destructor.

No, that's not the case. There is a temporary, but its destructor is not called. The existing object in `foo` is destroyed, so the new one can be moved (and indeed moved, not copied, so no postblit, no dtor call, though it might or might not invalidate internal pointers - that's why the spec bans those) into its place.
July 19, 2017
Yeah somehow I read that as a question -- must be getting tired.

That makes more sense.

is there any way to

On Wed, Jul 19, 2017 at 10:34 PM, Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Wednesday, 19 July 2017 at 12:23:06 UTC, Danni Coy wrote:
>
>> On Wed, Jul 19, 2017 at 7:09 PM, Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>>
>>
>>> What happens is this.
>>>
>>> void open()
>>> {
>>>   foo = () {
>>>   Foo _tmp = Foo.__ctor("test");
>>>   return _tmp;
>>>   } ();
>>> }
>>>
>>>
>>> Error: need 'this' for 'this' of type 'ref Foo(string s)'
>>>
>>
> I posted pseudo code to show you that you are creating a temporary.
> Which leaves the scope after assigning.
> And therefore triggers the destructor.
>


July 19, 2017
On Wednesday, 19 July 2017 at 09:09:40 UTC, Stefan Koch wrote:
> On Wednesday, 19 July 2017 at 07:48:28 UTC, Danni Coy wrote:
>> Is there a reason that the following code
>>
>> struct Foo
>> {
>>     this (string name)
>>     { do_something(name); }
>>
>>     ~this()
>>     { undo_something(); }
>> }
>>
>> Foo foo = void;
>>
>> void open()
>> {
>>     foo = Foo("test"); // <- this line
>> }
>>
>> tries to OpAssign foo to itself then calls foo's destructor?
>
> What happens is this.
>
> void open()
> {
>   foo = () {
>   Foo _tmp = Foo.__ctor("test");
>   return _tmp;
>   } ();
> }

Hm, isnt that wrong?
If I destroy resources on the dtor, wouldn't it invalidate the resource on the copy?
Also, C++ behaves differently

July 19, 2017
On Wednesday, 19 July 2017 at 14:09:32 UTC, SrMordred wrote:
> On Wednesday, 19 July 2017 at 09:09:40 UTC, Stefan Koch wrote:
>> On Wednesday, 19 July 2017 at 07:48:28 UTC, Danni Coy wrote:
>>> Is there a reason that the following code
>>>
>>> struct Foo
>>> {
>>>     this (string name)
>>>     { do_something(name); }
>>>
>>>     ~this()
>>>     { undo_something(); }
>>> }
>>>
>>> Foo foo = void;
>>>
>>> void open()
>>> {
>>>     foo = Foo("test"); // <- this line
>>> }
>>>
>>> tries to OpAssign foo to itself then calls foo's destructor?
>>
>> What happens is this.
>>
>> void open()
>> {
>>   foo = () {
>>   Foo _tmp = Foo.__ctor("test");
>>   return _tmp;
>>   } ();
>> }
>
> Hm, isnt that wrong?
> If I destroy resources on the dtor, wouldn't it invalidate the resource on the copy?
> Also, C++ behaves differently

No Sorry, it behaves almost the same.
just in D ctor and dtor are not called on declaration even if you drop " = void".
July 20, 2017
On Thu, Jul 20, 2017 at 12:19 AM, SrMordred via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Wednesday, 19 July 2017 at 14:09:32 UTC, SrMordred wrote:
>
>> On Wednesday, 19 July 2017 at 09:09:40 UTC, Stefan Koch wrote:
>>
>>> On Wednesday, 19 July 2017 at 07:48:28 UTC, Danni Coy wrote:
>>>
>>>> Is there a reason that the following code
>>>>
>>>> struct Foo
>>>> {
>>>>     this (string name)
>>>>     { do_something(name); }
>>>>
>>>>     ~this()
>>>>     { undo_something(); }
>>>> }
>>>>
>>>> Foo foo = void;
>>>>
>>>> void open()
>>>> {
>>>>     foo = Foo("test"); // <- this line
>>>> }
>>>>
>>>> tries to OpAssign foo to itself then calls foo's destructor?
>>>>
>>>
>>> What happens is this.
>>>
>>> void open()
>>> {
>>>   foo = () {
>>>   Foo _tmp = Foo.__ctor("test");
>>>   return _tmp;
>>>   } ();
>>> }
>>>
>>
>> Hm, isnt that wrong?
>> If I destroy resources on the dtor, wouldn't it invalidate the resource
>> on the copy?
>> Also, C++ behaves differently
>>
>
> No Sorry, it behaves almost the same.
> just in D ctor and dtor are not called on declaration even if you drop " =
> void".
>

Is there a way to delay the initialisation of a struct?


« First   ‹ Prev
1 2