# 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:

    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:

    1 2 3 1 2 3

However, the following is printed:

    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.

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.

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:

- Joost's Dev Blog. Hardcore C++: why "this" sometimes doesn't equal "this".

This diagnostic is classified as:

CWE-704