Undo struct slicing by type-punning
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?
Re: Undo struct slicing by type-punning
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?
Re: Undo struct slicing by type-punning
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: 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? 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 } Ali
Re: Undo struct slicing by type-punning
On Monday, 14 July 2014 at 18:43:36 UTC, Ali Çehreli wrote: 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. Well they are not really gone if the struct is passed by-ref, you can recover the gone parts: http://dpaste.dzfl.pl/d64863fd4c6d
Re: Undo struct slicing by type-punning
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.
Re: Undo struct slicing by type-punning
On 07/14/2014 02:34 PM, ponce wrote: On Monday, 14 July 2014 at 18:43:36 UTC, Ali Çehreli wrote: 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. Well they are not really gone if the struct is passed by-ref, 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. you can recover the gone parts: http://dpaste.dzfl.pl/d64863fd4c6d Aggreed 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