Undo struct slicing by type-punning

2014-07-14 Thread ponce via Digitalmars-d-learn

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

2014-07-14 Thread ponce via Digitalmars-d-learn
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

2014-07-14 Thread Ali Çehreli via Digitalmars-d-learn

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

2014-07-14 Thread ponce via Digitalmars-d-learn

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

2014-07-14 Thread ponce via Digitalmars-d-learn

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

2014-07-14 Thread Ali Çehreli via Digitalmars-d-learn

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