Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting between unrelated congruent classes

Tags:

c++

casting

Suppose I have two classes with identical members from two different libraries:

namespace A {
  struct Point3D {
    float x,y,z;
  };
}

namespace B {
  struct Point3D {
    float x,y,z;
  };
}

When I try cross-casting, it worked:

A::Point3D pa = {3,4,5};
B::Point3D* pb = (B::Point3D*)&pa;
cout << pb->x << " " << pb->y << " " << pb->z << endl;

Under which circumstances is this guaranteed to work? Always? Please note that it would be highly undesirable to edit an external library to add an alignment pragma or something like that. I'm using g++ 4.3.2 on Ubuntu 8.10.

like image 244
Jann Avatar asked Aug 11 '09 12:08

Jann


2 Answers

If the structs you are using are just data and no inheritance is used I think it should always work.

As long as they are POD it should be ok. http://en.wikipedia.org/wiki/Plain_old_data_structures

According to the standard(1.8.5)

"Unless it is a bit-field (9.6), a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Base class subobjects may have zero size. An object of POD5) type (3.9) shall occupy contiguous bytes of storage."

If they occupy contiguous bytes of storage and they are the same struct with different name, a cast should succeed

like image 194
Arkaitz Jimenez Avatar answered Oct 21 '22 12:10

Arkaitz Jimenez


If two POD structs start with the same sequence of members, the standard guarantees that you'll be able to access them freely through a union. You can store an A::Point3D in a union, and then read from the B::Point3D member, as long as you're only touching the members that are part of the initial common sequence. (so if one struct contained int, int, int, float, and the other contained int, int, int, int, you'd only be allowed to access the three first ints).

So that seems like one guaranteed way in which your code should work. It also means the cast should work, but I'm not sure if this is stated explicitly in the standard.

Of course all this assumes that both structs are compiled with the same compiler to ensure identical ABI.

like image 39
jalf Avatar answered Oct 21 '22 12:10

jalf