Thread overview
[Issue 21586] Struct dtor is called twice if struct is created inside ternary operator
Jan 27, 2021
RazvanN
Jan 27, 2021
Jack Applegame
Jan 27, 2021
Boris Carvajal
Jan 28, 2021
Boris Carvajal
Jan 28, 2021
Dlang Bot
Jan 31, 2021
Dlang Bot
Feb 13, 2021
Dlang Bot
January 26, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

moonlightsentinel@disroot.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |moonlightsentinel@disroot.o
                   |                            |rg

--- Comment #1 from moonlightsentinel@disroot.org ---
Modified:

extern (C) int printf(scope const char*, ...);

struct S
{
        this(int arg)
        {
                a = arg;
                printf("this(%d), this = %p\n", a, &this);
        }

    ~this()
    {
        printf("~this(%d), this = %p\n", a, &this);
    }

        int a;
}

void main()
{
        auto s = true ? S(1) : S(0);
    printf("main\n");
}

----

this(1), this = 0x7fff3b745b88
~this(1), this = 0x7fff3b745b88
main
~this(1), this = 0x7fff3b745b98

---

So there's only one dtor call for the temporary created inside of the ternary operator and another call for the variable s at the end of main.

--
January 27, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |razvan.nitu1305@gmail.com
         Resolution|---                         |INVALID

--- Comment #2 from RazvanN <razvan.nitu1305@gmail.com> ---
(In reply to Temtaime from comment #0)

As moonlightsentinel highlighted, the variable is destroyed only once. The code in main is roughly translated to this:

void main()
{
    S tmp;
    auto s = (true ? tmp = S(1) : tmp = S(0); tmp);
    tmp.__dtor;
    s.__dtor;
}

This is the intended behavior. Closing as invalid.

--
January 27, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

Jack Applegame <japplegame@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |japplegame@gmail.com

--- Comment #3 from Jack Applegame <japplegame@gmail.com> ---
But if you add a copy constructor to the structure, no temporary copy is
created.
It's weird, but acceptable.

--
January 27, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

Boris Carvajal <boris2.9@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |boris2.9@gmail.com

--- Comment #4 from Boris Carvajal <boris2.9@gmail.com> ---
The temporary variable also disappears when there's a postblit.

AST generated when a postblit or copy constructor is present:

    S s = (true) ? s = 0 , s.this(1) : (s = 0 , s.this(0));

In the original case:

    S s = (true) ? (S(0)).this(1) : (S(0)).this(0);

Looks like a frontend bad decision, there's no reason to not generate the equivalent code to a simple assignment. For example:

    S s = S(1);

generates:

    S s = s = 0 , s.this(1);

--
January 28, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

Boris Carvajal <boris2.9@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |---

--
January 28, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #5 from Dlang Bot <dlang-bot@dlang.rocks> ---
@BorisCarvajal created dlang/dmd pull request #12163 "Fix Issue 21586 - Struct dtor is called twice if struct is created in…" fixing this issue:

- Fix Issue 21586 - Struct dtor is called twice if struct is created inside ternary operator

https://github.com/dlang/dmd/pull/12163

--
January 31, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #12163 "Fix Issue 21586 - Struct dtor is called twice if struct is created in…" was merged into stable:

- 9ca0687a06db987e12581ca216445976b559fae4 by Boris Carvajal:
  Fix Issue 21586 - Struct dtor is called twice if struct is created inside
ternary operator

https://github.com/dlang/dmd/pull/12163

--
February 13, 2021
https://issues.dlang.org/show_bug.cgi?id=21586

--- Comment #7 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #12195 "Merge stable" was merged into master:

- a3b4319bd1aa9a92db46bf61bcc2feb2ab668b7f by Boris Carvajal:
  Fix Issue 21586 - Struct dtor is called twice if struct is created inside
ternary operator (#12163)

https://github.com/dlang/dmd/pull/12195

--