Thursday, August 3, 2017

Polymorphism and Aliasing

Someone recently asked me about strict aliasing, which is where two pointers of different types point to the same memory. The question came up whether you can have two pointers of sibling types point to each other. The answer is, not safely!

Consider the following:

   class A  
   {  
   public:  
     uint64_t mylong;  
   };  
   class B : public A  
   {  
   public:  
     uint32_t myint;  
     uint32_t myint2;  
   };  
   class C : public A  
   {  
   public:  
     uint64_t mylong2;  
     uint64_t mylong3;  
   };  
   int main(int argc, char** argv)  
   {  
     B* b = new B();  
     b->myint = 0;  
     C* c = (C*)b;  
     printf("%u %lu\n", b->myint, c->mylong3);  
   }  

Assuming an 8 byte alignment, we get the following sizes for these classes:
A: 8
B: 16
C: 24

When we alias our pointer c to b, we are taking a 24 byte long type and pointing at 16 bytes of memory! This means, when we access c->mylong3, we are accessing memory that has not been allocated yet!

Likewise, you should not create a new A type object, and then alias a B or C type pointer to it, as the extra memory for members other than mylong has not been allocated.

No comments:

Post a Comment