﻿# V725\. Dangerous cast of 'this' to 'void\*' type in the 'Base' class, as it is followed by a subsequent cast to 'Class' type\.

The analyzer has detected a dangerous casting of the this pointer to the void\* type followed by a cast of void\* back to the class type\. Casting this to void\* is not an error, but in certain cases, casting void\* back to the class pointer is\. Such conversions may lead to an invalid pointer\.

Here is an example where `this` is cast to `void*`, followed by an invalid cast back to the class type:



```cpp
class A
{
public:
  A() : firstPart(1){}
  void printFirstPart() { std::cout << firstPart << " "; }
private:
  int firstPart;
};

class B
{
public:
  B() : secondPart(2){}
  void* GetAddr() const { return (void*)this;  }
  void printSecondPart() { std::cout << secondPart << " "; }
private:
  int secondPart;
};

class C: public A, public B
{
public:
  C() : A(), B(), thirdPart(3){}
  void printThirdPart() { std::cout << thirdPart << " "; }
private:
  int thirdPart;
};
void func()
{
  C someObject;

  someObject.printFirstPart();
  someObject.printSecondPart();
  someObject.printThirdPart();

  void *pointerToObject = someObject.GetAddr();
  ....
  auto pointerC = static_cast<C*>(pointerToObject);

  pointerC->printFirstPart();
  pointerC->printSecondPart();
  pointerC->printThirdPart();
}
```

One might assume that the output would be as follows:

```cpp
1 2 3 1 2 3
```

However, the following is printed:

```cpp
1 2 3 2 3 -858993460
```

As a result, the output for all data after conversions is incorrect\. The issue is that now `pointerC` points to the memory block allocated for the `B` object rather than to the beginning of the `C` object\.

This error may seem farfetched and unreal, but it is only obvious because the example above is short and simple\. In real\-life programs with complex class hierarchies, it may be far vaguer\. The most confusing part is that the `GetAddr()` function works when it's in the `A` class, but fails when placed in the `B` class\.

To easily understand what caused the error, programmers need to know how class objects created using multiple inheritance are constructed and arranged in memory\.

A schematic example is shown in the Figure 1\.

![V725/image1.png](https://import.viva64.com/docx/blog/V725/image1.png)

Figure 1—The memory layout of a class object created through multiple inheritance\.

The `C` class object, obtained as a result of multiple inheritance, consists of the `A` and `B` class objects, as well as a part of the `C` object\.

The `this` pointer points to the beginning of the memory block allocated for the object\. The Figure 2 shows `this` pointers for all the three objects\.



![V725/image2.png](https://import.viva64.com/docx/blog/V725/image2.png)

Figure 2—The `this` pointers and memory blocks\.

Since the `C` class object consists of three parts, its `this` pointer points to the beginning of the entire continuous memory block rather than to an additional one\. That is, `this` pointers for the `A` and `C` classes match in this case\.

The `this` pointer for the `B` class object points to the beginning of the memory block allocated for it, but its address differs from the starting address of the memory block allocated for the `C` class object\.

So, when calling the `GetAddr()` method, a programmer gets the address of the `B` object and then, after casting the resulting pointer back to the `C*` type , they get an incorrect pointer\.

In other words, if the `GetAddr()` function were stored in the `A` class, the program would work as expected, but when it is stored in `B`, a developer gets an error\.

To avoid such errors, programmers should consider whether they really need to cast `this` to `void*`\. If the answer is yes, they need to carefully check the inheritance hierarchy and any casts of `void*` back to the class pointer type\.

**References:**

1. Joost's Dev Blog\. [Hardcore C\+\+: why "this" sometimes doesn't equal "this"](http://joostdevblog.blogspot.com/2013/03/hardcore-c-why-this-sometimes-doesnt.html)\.