Thread overview
[Issue 12918] Copying-constructing structs onto the heap
Jun 14, 2014
Jonathan M Davis
Jun 14, 2014
Jonathan M Davis
Jun 15, 2014
Matt Kline
Jul 23, 2016
Thayne
Dec 17, 2022
Iain Buclaw
June 14, 2014
https://issues.dlang.org/show_bug.cgi?id=12918

Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Copying structs on the heap |Copying-constructing
                   |                            |structs onto the heap

--
June 14, 2014
https://issues.dlang.org/show_bug.cgi?id=12918

bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc

--- Comment #1 from bearophile_hugs@eml.cc ---
(In reply to Jonathan M Davis from comment #0)

> I think that this code should compile
> 
> struct Foo
> {
>     int i;
> }
> 
> void main()
> {
>     auto f = Foo(5);
>     auto g = new Foo(f);
> }

Implicit functionality cause problems, so you need something significant to justify its presence. What are some use cases of code like that?

--
June 14, 2014
https://issues.dlang.org/show_bug.cgi?id=12918

--- Comment #2 from Jonathan M Davis <jmdavisProg@gmx.com> ---
> Implicit functionality cause problems, so you need something significant to justify its presence. What are some use cases of code like that?

It's inconsistent that it doesn't work. Copying on the stack works just fine already, why shouldn't it just work for you to be able to construct an object on the heap which is a copy of one on the stack? And this code works right now

void main()
{
    int i = 5;
    auto j = new int(i);
}

It just doesn't work with structs for some reason. As it stands, you're forced to either do something like

auto g = new Foo;
*g = f;

which is overly verbose and doesn't work with const or immutable, or you're forced to create an extra constructor that basically does what a postblit already does except that it's for the heap. So, this affects all code that wants to create a copy of a struct on the heap.

Also, I don't see how the requested behavior could cause any problems. The only code which would be affected is code that already defines a constructor which takes a variable of the same type, and that could continue to work as it does now. Code that doesn't do that could then start taking advantage of the new behavior it wanted to, but all this is doing is the exact same thing that a postlblit constructor does except on the heap, and postblit constructors are already implicitly defined if you don't defined them. And I would fully expect that this feature would use the postblit constructor. It's just that it would then be copying to the heap rather than the stack.

--
June 15, 2014
https://issues.dlang.org/show_bug.cgi?id=12918

Matt Kline <mkline.on.d@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mkline.on.d@gmail.com

--- Comment #3 from Matt Kline <mkline.on.d@gmail.com> ---
(In reply to bearophile_hugs from comment #1)

> What are some use cases of code like that?

Say struct Foo has a member Bar* b, which can either contain some optional data or be null to indicate that no such data is currently present.

>From some other data structure, you procure an instance of Bar (call it other)
which you would like to assign to b. However, to make the lifetime of b independent of its source, you want to create a garbage-collected copy of other and assign it to b.

--
June 09, 2015
https://issues.dlang.org/show_bug.cgi?id=12918

Andrei Alexandrescu <andrei@erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|unspecified                 |D2

--
July 23, 2016
https://issues.dlang.org/show_bug.cgi?id=12918

Thayne <astrothayne@gmail.com> changed:

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

--- Comment #4 from Thayne <astrothayne@gmail.com> ---
A workaround for this is to allocate a Foo then assign it to the struct.

struct Foo
{
    int i;
}

void main()
{
    auto f = Foo(5);
    auto g = new Foo;
    *g = f;
}

However, if the Foo struct has the default constructor disabled (@disable this();) then this doesn't work, even if postblit isn't disabled. The only way I can think of to get this to work in general would be something like this:

auto f= Foo(5);
auto g = cast(Foo*) (new ubyte[Foo.sizeof]).ptr;
*g = f;

which is pretty awkward.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=12918

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P4

--
December 13
https://issues.dlang.org/show_bug.cgi?id=12918

--- Comment #5 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/18838

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--