You have already received the correct answer, and this is really a violation of the strict alias rule, which leads to unpredictable code behavior. I would only note that the title of your question makes a link to "drop the pointer to the source class". In fact, your code has nothing to do with back casting. Your code reinterprets the contents of the raw memory occupied by the void * pointer as the A * pointer. This is not a drop. This is a reinterpretation. Not even remotely the same.
A good way to illustrate the difference would be to use both int and float example. float value declared and initialized as
float f = 2.0;
the cabin will be transformed (explicitly or implicitly converted) to int type
int i = (int) f;
with expected result
assert(i == 2);
It really is a throw (conversion).
Alternatively, the same float value can also be interpreted as an int value
int i = (int &) f;
However, in this case, the value of i will be completely meaningless and generally unpredictable. I hope it is easy to see the difference between memory conversion and reinterpretation from these examples.
Reinterpretation is exactly what you do in your code. The expression (A *&) p is nothing more than a reinterpretation of the raw memory occupied by the void *p pointer as an A * type pointer. The language does not guarantee that these two types of pointers have the same representation and the same size. So, expecting the predictable behavior of your code will look like the expression above (int &) f will evaluate to 2 .
The proper way to drop your void * pointer should be to make (A *) p , not (A *&) p . The result of (A *) p indeed be the original value of the pointer, which can be safely manipulated using pointer arithmetic. The only right way to get the original value as an lvalue would be to use an extra variable
A *pa = (A *) p; ... pa++; ...
And there is no legal way to create an “in place” lvalue, as you tried to make your (A *&) p . The behavior of your code is an illustration of this.
source share