digitalmars.D - Copy a struct on the heap and get the pointer to it.
- deadalnix (16/16) Nov 12 2011 Hi all,
- Timon Gehr (5/22) Nov 12 2011 Yes.
- kenji hara (34/63) Nov 12 2011 Here is a pitfall.
- Andrei Alexandrescu (5/23) Nov 12 2011 Thanks! This is important. I recall C++ was much more difficult to use
- deadalnix (6/31) Nov 12 2011 Well I don't think the postblit should be called if s isn't used after
- Adam D. Ruppe (5/5) Nov 12 2011 The way I'd do it is:
- Timon Gehr (4/9) Nov 12 2011 struct S{
- Martin Nowak (7/12) Nov 12 2011 auto ps = std.conv.emplace(new S, s);
- Andrei Alexandrescu (4/21) Nov 12 2011 That should work but it's rather complicated.
- Vladimir Panteleev (6/7) Nov 12 2011 Won't work if S has a constructor (which was the OP's case).
- Andrei Alexandrescu (7/14) Nov 12 2011 This should work:
- Timon Gehr (4/20) Nov 12 2011 It does not work for structs either. It fails with 'Error: no
- Martin Nowak (3/20) Nov 12 2011 Yes it should, but it doesn't.
- kenji hara (4/22) Nov 12 2011 It has been already filed in bugzilla?
- deadalnix (2/19) Nov 12 2011 That was my first try. It does not work.
- Martin Nowak (5/30) Nov 12 2011 =
- Martin Nowak (9/38) Nov 12 2011 p =
- Martin Nowak (7/24) Nov 12 2011 Not so sure about built-in types. It's preferable for generic code to
Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the struct What is going on ? An array of one object is allocated on the heap and the struct copied in it. Then we get a pointer to the first (and only one) element of the array with ptr. So we have a pointer to a copy of s on the heap. I have several question on that : - Does a idiomatic way to do that exists ? - Is this intented to do so ? Will this construct risk to be broken in a future version of D ? - Is this construct the idiomatic way to do so ?
Nov 12 2011
On 11/12/2011 03:39 PM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the struct What is going on ? An array of one object is allocated on the heap and the struct copied in it. Then we get a pointer to the first (and only one) element of the array with ptr. So we have a pointer to a copy of s on the heap. I have several question on that : - Does a idiomatic way to do that exists ?I don't think that this is such a common need.- Is this intented to do so ?Yes.Will this construct risk to be broken in a future version of D ?No.- Is this construct the idiomatic way to do so ?It is certainly the most elegant way to do so.
Nov 12 2011
Here is a pitfall. If S has the postblit, it is not called with your code. import core.stdc.stdio; struct S { this(this){ printf("postblit\n"); } } void main() { S s; S* ps = [s].ptr; // does not print "postblit" } I've already poted a pull (https://github.com/D-Programming-Language/dmd/pull/375) to fix it, but it is not yet merged. A workaround is follows. // The definition of S is same as above. T makecopy(T)(ref T obj) if (is(T == struct)) { auto dup = obj; // make copy with calling postblit return dup; } void main() { S s; S* ps = [makecopy(s)].ptr; // print "postblit" } If you use it, please be careful. Kenji Hara. 2011/11/13 Timon Gehr <timon.gehr gmx.ch>:On 11/12/2011 03:39 PM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the struct What is going on ? An array of one object is allocated on the heap and the struct copied in it. Then we get a pointer to the first (and only one) element of the array with ptr. So we have a pointer to a copy of s on the heap. I have several question on that : - Does a idiomatic way to do that exists ?I don't think that this is such a common need.- Is this intented to do so ?Yes.Will this construct risk to be broken in a future version of D ?No.- Is this construct the idiomatic way to do so ?It is certainly the most elegant way to do so.
Nov 12 2011
On 11/12/11 9:22 AM, kenji hara wrote:Here is a pitfall. If S has the postblit, it is not called with your code. import core.stdc.stdio; struct S { this(this){ printf("postblit\n"); } } void main() { S s; S* ps = [s].ptr; // does not print "postblit" } I've already poted a pull (https://github.com/D-Programming-Language/dmd/pull/375) to fix it, but it is not yet merged.Thanks! This is important. I recall C++ was much more difficult to use in the period of time where compilers got various copy construction scenarios wrong. We need to have object copying rock-solid. Andrei
Nov 12 2011
Le 12/11/2011 16:27, Andrei Alexandrescu a écrit :On 11/12/11 9:22 AM, kenji hara wrote:Well I don't think the postblit should be called if s isn't used after the copy on the heap. This should have the move semantic and not the copy semantic. Obviously, if s is used after the copy on the heap, the postblit should be called.Here is a pitfall. If S has the postblit, it is not called with your code. import core.stdc.stdio; struct S { this(this){ printf("postblit\n"); } } void main() { S s; S* ps = [s].ptr; // does not print "postblit" } I've already poted a pull (https://github.com/D-Programming-Language/dmd/pull/375) to fix it, but it is not yet merged.Thanks! This is important. I recall C++ was much more difficult to use in the period of time where compilers got various copy construction scenarios wrong. We need to have object copying rock-solid. Andrei
Nov 12 2011
The way I'd do it is: S s; auto heap = new S; *heap = s; that should work.
Nov 12 2011
On 11/12/2011 04:17 PM, Adam D. Ruppe wrote:The way I'd do it is: S s; auto heap = new S; *heap = s; that should work.struct S{ immutable no_it_does_not = 0; // ;) }
Nov 12 2011
On Sat, 12 Nov 2011 16:17:29 +0100, Adam D. Ruppe <destructionator gmail.com> wrote:The way I'd do it is: S s; auto heap = new S; *heap = s; that should work.auto ps = std.conv.emplace(new S, s); Avoids the hacky array aliasing. // slightly more efficient auto ps2 = emplace(cast(S*)(new ubyte[](S.sizeof)).ptr, s); You will need to define a copy constructor for immutable fields.
Nov 12 2011
On 11/12/11 9:37 AM, Martin Nowak wrote:On Sat, 12 Nov 2011 16:17:29 +0100, Adam D. Ruppe <destructionator gmail.com> wrote:That constructs S two times.The way I'd do it is: S s; auto heap = new S; *heap = s; that should work.auto ps = std.conv.emplace(new S, s); Avoids the hacky array aliasing.// slightly more efficient auto ps2 = emplace(cast(S*)(new ubyte[](S.sizeof)).ptr, s); You will need to define a copy constructor for immutable fields.That should work but it's rather complicated. Andrei
Nov 12 2011
On Sat, 12 Nov 2011 17:17:29 +0200, Adam D. Ruppe <destructionator gmail.com> wrote:auto heap = new S;Won't work if S has a constructor (which was the OP's case). -- Best regards, Vladimir mailto:vladimir thecybershadow.net
Nov 12 2011
On 11/12/11 8:39 AM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work. Andrei
Nov 12 2011
On 11/12/2011 04:29 PM, Andrei Alexandrescu wrote:On 11/12/11 8:39 AM, deadalnix wrote:It does not work for structs either. It fails with 'Error: no constructor for S'. Where is the behaviour you describe documented?Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work.
Nov 12 2011
On Sat, 12 Nov 2011 16:29:01 +0100, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 11/12/11 8:39 AM, deadalnix wrote:Yes it should, but it doesn't.Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work. Andrei
Nov 12 2011
It has been already filed in bugzilla? If so, I'd like to fix it. Kenji Hara 2011/11/13 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:On 11/12/11 8:39 AM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work. Andrei
Nov 12 2011
Le 12/11/2011 16:29, Andrei Alexandrescu a écrit :On 11/12/11 8:39 AM, deadalnix wrote:That was my first try. It does not work.Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work. Andrei
Nov 12 2011
On Sat, 12 Nov 2011 17:41:43 +0100, deadalnix <deadalnix gmail.com> wrot= e:Le 12/11/2011 16:29, Andrei Alexandrescu a =C3=A9crit :=On 11/12/11 8:39 AM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the heap=rand getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p =3D new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't fo=I'll make bug reports for it.primitive types, e.g. new int(5) does not work. AndreiThat was my first try. It does not work.
Nov 12 2011
On Sat, 12 Nov 2011 17:41:56 +0100, Martin Nowak <dawg dawgfoto.de> wrot= e:On Sat, 12 Nov 2011 17:41:43 +0100, deadalnix <deadalnix gmail.com> =wrote:p =Le 12/11/2011 16:29, Andrei Alexandrescu a =C3=A9crit :On 11/12/11 8:39 AM, deadalnix wrote:Hi all, We recently had a discution on #D about copying a struct on the hea=orand getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p =3D new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't f=http://d.puremagic.com/issues/show_bug.cgi?id=3D6937 http://d.puremagic.com/issues/show_bug.cgi?id=3D6938 It's actually two bugs. If the 6937 worked one could have used 'new S(s.tupleof)'. martinI'll make bug reports for it.primitive types, e.g. new int(5) does not work. AndreiThat was my first try. It does not work.
Nov 12 2011
On Sat, 12 Nov 2011 16:29:01 +0100, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 11/12/11 8:39 AM, deadalnix wrote:Not so sure about built-in types. It's preferable for generic code to define 'Type(Expression)' as initializer, but is there a consensus for 'int(3)'? Also as it is allowed for structs there should be no ambiguities with function signatures, still this needs a thorough thought.Hi all, We recently had a discution on #D about copying a struct on the heap and getting a pointer to it. We come up with the following solution (Thanks to CyberShadow !) : struct S; S s; // Allocated locally. [s].ptr; // Get a pointer to a copy in the heap of the structThis should work: S s; auto p = new S(s); It's a bug in the compiler if it doesn't. Unfortunately it doesn't for primitive types, e.g. new int(5) does not work. Andrei
Nov 12 2011