digitalmars.D.learn - Copy a struct and its context
- Yuxuan Shui (6/6) Sep 10 2016 I recently noticed nested struct capture its context by reference
- Rene Zwanenburg (4/10) Sep 11 2016 I've tried a few things, but I don't think you can. The root
- =?UTF-8?Q?Ali_=c3=87ehreli?= (17/22) Sep 12 2016 Can you show a small example? This seems to work:
- Steven Schveighoffer (21/44) Sep 12 2016 " It has access to the context of its enclosing scope (via an added
- Yuxuan Shui (8/19) Sep 13 2016 Why not just capture the variables that are actually been
- Steven Schveighoffer (18/36) Sep 13 2016 Again, could be clearer. But the fact that both the function and the
- Yuxuan Shui (4/27) Sep 13 2016 It just feels a bit tedious to do something manually while the
- Steven Schveighoffer (8/23) Sep 13 2016 Do what for you? How does it know that you don't want to use a closure
- Yuxuan Shui (11/38) Sep 13 2016 For example, a common use case might be I want to capture
- Steven Schveighoffer (5/13) Sep 13 2016 This is a valid enhancement. Why not try and ask for it?
- Basile B. (3/14) Sep 13 2016 with stack stomp no way that any hack could work, if any.
I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested). And bliting a struct obviously doesn't do a deep copy of its context. So my question is, is there a way to deep copy the context of a struct?
Sep 10 2016
On Sunday, 11 September 2016 at 05:44:13 UTC, Yuxuan Shui wrote:I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested). And bliting a struct obviously doesn't do a deep copy of its context. So my question is, is there a way to deep copy the context of a struct?I've tried a few things, but I don't think you can. The root issue is that the context pointer is void*, so you can't do meaningful reflection on it.
Sep 11 2016
On 09/10/2016 10:44 PM, Yuxuan Shui wrote:I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested). And bliting a struct obviously doesn't do a deep copy of its context. So my question is, is there a way to deep copy the context of a struct?Can you show a small example? This seems to work: auto foo(int i) { struct S { int foo() { return i; } } return S(); } void main() { auto s = foo(42); auto s_copy = s; assert(s.foo() == 42); assert(s_copy.foo() == 42); } Ali
Sep 12 2016
On 9/12/16 4:11 PM, Ali Çehreli wrote:On 09/10/2016 10:44 PM, Yuxuan Shui wrote:" It has access to the context of its enclosing scope (via an added hidden field)." It needs to be a reference. Otherwise, you store the entire stack frame in the struct? That wouldn't be a "field". It also has write access to the context: void foo() { int i; struct S { void changeI(int newVal) { i = newVal; } } S s; s.changeI(10); assert(i == 10); } The documentation could be clearer.I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested).And bliting a structHe wants to deep-copy the struct, meaning copy the context pointer data. Meaning if you change 'i' in s, then s_copy's foo still returns 42. I don't think it is or should be doable. -Steveobviously doesn't do a deep copy of its context. So my question is, is there a way to deep copy the context of a struct?Can you show a small example? This seems to work: auto foo(int i) { struct S { int foo() { return i; } } return S(); } void main() { auto s = foo(42); auto s_copy = s; assert(s.foo() == 42); assert(s_copy.foo() == 42); }
Sep 12 2016
On Tuesday, 13 September 2016 at 01:32:19 UTC, Steven Schveighoffer wrote:On 9/12/16 4:11 PM, Ali Çehreli wrote:Why not just capture the variables that are actually been referenced? Also being a field doesn't put limits on the size of the "field". I like how C++ lambda lets you choose what variables to capture, and how are they captured. I'm little disappointed that D doesn't let me do the same.On 09/10/2016 10:44 PM, Yuxuan Shui wrote:" It has access to the context of its enclosing scope (via an added hidden field)." It needs to be a reference. Otherwise, you store the entire stack frame in the struct? That wouldn't be a "field". It also has write access to the context:I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested).
Sep 13 2016
On 9/13/16 3:42 PM, Yuxuan Shui wrote:On Tuesday, 13 September 2016 at 01:32:19 UTC, Steven Schveighoffer wrote:There's nothing in the language to prevent this optimization.On 9/12/16 4:11 PM, Ali Çehreli wrote:Why not just capture the variables that are actually been referenced?On 09/10/2016 10:44 PM, Yuxuan Shui wrote:" It has access to the context of its enclosing scope (via an added hidden field)." It needs to be a reference. Otherwise, you store the entire stack frame in the struct? That wouldn't be a "field". It also has write access to the context:I recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested).Also being a field doesn't put limits on the size of the "field".Again, could be clearer. But the fact that both the function and the struct affect the same data kind of dictates it needs to be a reference.I like how C++ lambda lets you choose what variables to capture, and how are they captured. I'm little disappointed that D doesn't let me do the same.Not familiar with C++ lambda. You can always "specify" how to capture the data by directly declaring it: auto foo() { int x; static struct S { int x; } return S(x); } In D, if you have a closure, it's going to be heap allocated. Just the way it is. If you don't want that, you have to avoid them. -Steve
Sep 13 2016
On Tuesday, 13 September 2016 at 20:00:40 UTC, Steven Schveighoffer wrote:On 9/13/16 3:42 PM, Yuxuan Shui wrote:It just feels a bit tedious to do something manually while the compiler have enough information to do it for me.[...]There's nothing in the language to prevent this optimization.[...]Again, could be clearer. But the fact that both the function and the struct affect the same data kind of dictates it needs to be a reference.[...]Not familiar with C++ lambda. You can always "specify" how to capture the data by directly declaring it: auto foo() { int x; static struct S { int x; } return S(x); }In D, if you have a closure, it's going to be heap allocated. Just the way it is. If you don't want that, you have to avoid them. -Steve
Sep 13 2016
On 9/13/16 4:11 PM, Yuxuan Shui wrote:On Tuesday, 13 September 2016 at 20:00:40 UTC, Steven Schveighoffer wrote:Do what for you? How does it know that you don't want to use a closure and a reference to that instead? Note that all the internals for this are implementation defined. Given sufficient conditions, the compiler could "cheat" and allocate the data inside the struct itself instead. For example, if all referenced data was immutable. -SteveNot familiar with C++ lambda. You can always "specify" how to capture the data by directly declaring it: auto foo() { int x; static struct S { int x; } return S(x); }It just feels a bit tedious to do something manually while the compiler have enough information to do it for me.
Sep 13 2016
On Tuesday, 13 September 2016 at 20:36:22 UTC, Steven Schveighoffer wrote:On 9/13/16 4:11 PM, Yuxuan Shui wrote:For example, a common use case might be I want to capture everything by value. In stead of adding all the fields by hand and passing them to the constructor, I want the compiler to do it for me. i.e. I wish I could (borrowing C++ syntax): struct A[=] { ... } Then the context will be captured by value instead of reference.On Tuesday, 13 September 2016 at 20:00:40 UTC, Steven Schveighoffer wrote:Do what for you? How does it know that you don't want to use a closure and a reference to that instead? Note that all the internals for this are implementation defined. Given sufficient conditions, the compiler could "cheat" and allocate the data inside the struct itself instead. For example, if all referenced data was immutable. -SteveNot familiar with C++ lambda. You can always "specify" how to capture the data by directly declaring it: auto foo() { int x; static struct S { int x; } return S(x); }It just feels a bit tedious to do something manually while the compiler have enough information to do it for me.
Sep 13 2016
On 9/13/16 5:01 PM, Yuxuan Shui wrote:For example, a common use case might be I want to capture everything by value. In stead of adding all the fields by hand and passing them to the constructor, I want the compiler to do it for me. i.e. I wish I could (borrowing C++ syntax): struct A[=] { ... } Then the context will be captured by value instead of reference.This is a valid enhancement. Why not try and ask for it? I don't know if the specific syntax would work for D, but the feature seems useful in some respects. -Steve
Sep 13 2016
On Tuesday, 13 September 2016 at 01:32:19 UTC, Steven Schveighoffer wrote:On 9/12/16 4:11 PM, Ali Çehreli wrote:with stack stomp no way that any hack could work, if any.On 09/10/2016 10:44 PM, Yuxuan Shui wrote:He wants to deep-copy the struct, meaning copy the context pointer data. Meaning if you change 'i' in s, then s_copy's foo still returns 42. I don't think it is or should be doable. -SteveI recently noticed nested struct capture its context by reference (which, BTW, is not mentioned at all here: https://dlang.org/spec/struct.html#nested).
Sep 13 2016