digitalmars.D.learn - Undo struct slicing by type-punning
- ponce (28/28) Jul 14 2014 Hi,
- ponce (3/32) Jul 14 2014 Ok, solved it, I just use pointer casts and it seems to work when
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (11/51) Jul 14 2014 I think there is a terminology issue here. Slicing cannot be undone;
- ponce (3/9) Jul 14 2014 Well they are not really gone if the struct is passed by-ref, you
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (13/25) Jul 14 2014 Oh, it's not slicing in that case... but wait! There is a problem here. ...
- ponce (2/10) Jul 14 2014 Indeed, the code I port do that because struct have a type-tag.
Hi, I am porting C++ code that undo "Object Slicing" by casting const-references: http://en.wikipedia.org/wiki/Object_slicing My translation in D Code ---- struct A { // stuff } struct B { A a; alias a this; // stuff } void myFunction(ref const(A) a) { if (<a-is-actually-a-B>) { // here goes the converstion to a B reference myFunction2(*cast(const(B)*)(&a)); // using pointer to do type-punning } } ---- To do this, I need to by guaranteed an object passed through ref const(A) is never, ever passed by value. Is it safe to assume?
Jul 14 2014
Ok, solved it, I just use pointer casts and it seems to work when the struct is sliced. On Monday, 14 July 2014 at 13:23:57 UTC, ponce wrote:Hi, I am porting C++ code that undo "Object Slicing" by casting const-references: http://en.wikipedia.org/wiki/Object_slicing My translation in D Code ---- struct A { // stuff } struct B { A a; alias a this; // stuff } void myFunction(ref const(A) a) { if (<a-is-actually-a-B>) { // here goes the converstion to a B reference myFunction2(*cast(const(B)*)(&a)); // using pointer to do type-punning } } ---- To do this, I need to by guaranteed an object passed through ref const(A) is never, ever passed by value. Is it safe to assume?
Jul 14 2014
On 07/14/2014 10:35 AM, ponce wrote:Ok, solved it, I just use pointer casts and it seems to work when the struct is sliced.I think there is a terminology issue here. Slicing cannot be undone; once the object is sliced, the non-A parts are gone.On Monday, 14 July 2014 at 13:23:57 UTC, ponce wrote:It is guaranteed by the language spec that yes, myFunction() takes an A by reference. However, you can't know where that A is coming from; so, the safety of that cast is up to you. Consider: void foo(A a) // <-- Already sliced { myFunction(a); // <-- Will perform invalid cast } AliHi, I am porting C++ code that undo "Object Slicing" by casting const-references: http://en.wikipedia.org/wiki/Object_slicing My translation in D Code ---- struct A { // stuff } struct B { A a; alias a this; // stuff } void myFunction(ref const(A) a) { if (<a-is-actually-a-B>) { // here goes the converstion to a B reference myFunction2(*cast(const(B)*)(&a)); // using pointer to do type-punning } } ---- To do this, I need to by guaranteed an object passed through ref const(A) is never, ever passed by value. Is it safe to assume?
Jul 14 2014
On Monday, 14 July 2014 at 18:43:36 UTC, Ali Çehreli wrote:On 07/14/2014 10:35 AM, ponce wrote:Well they are not really gone if the struct is passed by-ref, you can recover the "gone" parts: http://dpaste.dzfl.pl/d64863fd4c6dOk, solved it, I just use pointer casts and it seems to workwhen thestruct is sliced.I think there is a terminology issue here. Slicing cannot be undone; once the object is sliced, the non-A parts are gone.
Jul 14 2014
On 07/14/2014 02:34 PM, ponce wrote:On Monday, 14 July 2014 at 18:43:36 UTC, Ali Çehreli wrote:Oh, it's not slicing in that case... but wait! There is a problem here. :) In C++, both structs and classes are value types and they both support inheritance. To observe slicing in C++, one needs pass-by-value and inheritance, which is available by structs and classes. In D, structs don't support inheritance and classes don't support pass-by-value. However... Enter 'alias this' and we have D's version of slicing.On 07/14/2014 10:35 AM, ponce wrote:Well they are not really gone if the struct is passed by-ref,Ok, solved it, I just use pointer casts and it seems to workwhen thestruct is sliced.I think there is a terminology issue here. Slicing cannot be undone; once the object is sliced, the non-A parts are gone.you can recover the "gone" parts: http://dpaste.dzfl.pl/d64863fd4c6dAggreed but in D's case the non-A parts are not gone; as long as A lives, we know that B is alive. This is different from C++ where due to the necessary pass-by-value, they are truly gone (the bits may still be there but a C++ code should not do as D does). Ali
Jul 14 2014
On Monday, 14 July 2014 at 18:43:36 UTC, Ali Çehreli wrote:It is guaranteed by the language spec that yes, myFunction() takes an A by reference. However, you can't know where that A is coming from; so, the safety of that cast is up to you. Consider: void foo(A a) // <-- Already sliced { myFunction(a); // <-- Will perform invalid cast }Indeed, the code I port do that because struct have a type-tag.
Jul 14 2014