Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
July 14, 2014 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? |
July 14, 2014 Re: Undo struct slicing by type-punning | ||||
---|---|---|---|---|
| ||||
Posted in reply to ponce | 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?
|
July 14, 2014 Re: Undo struct slicing by type-punning | ||||
---|---|---|---|---|
| ||||
Posted in reply to ponce | 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 |
July 14, 2014 Re: Undo struct slicing by type-punning | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 |
July 14, 2014 Re: Undo struct slicing by type-punning | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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.
|
July 14, 2014 Re: Undo struct slicing by type-punning | ||||
---|---|---|---|---|
| ||||
Posted in reply to ponce | 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 |
Copyright © 1999-2021 by the D Language Foundation