Eric
11/4/2008 9:47:00 PM
On Nov 4, 4:42 pm, Noah Roberts <u...@example.net> wrote:
> Eric wrote
>
> > In LibraryB, there is a function called test. This function takes a
> > void *, which will end up being a function pointer to the GetA
> > function from LibraryA.
>
> > The problem comes in the test function with the line:
>
> > B* myB = dynamic_cast<B*> (myA);
>
> > The dynamic_cast fails and myB is assigned NULL. This _should not_
> > fail because myA is an instance of class B.
>
> A lot of people make the mistake of casting in and out of void* using
> different types. This will cause UB. The reason being can be seen in
> 4.10.2:
>
> The result of converting a "pointer to cv T" to a "pointer to cv void"
> points to the start of the storage location where the object of type T
> resides, as if the object is a most derived object (1.8) of type T (that
> is, not a base class subobject).
>
> In other words, if you cast a B* to a void*, then cast that void* to an
> A* (or visa-versa) you're going to have serious problems. The A* will
> now, possibly incorrectly, point to a location in memory that is a B*
> without the correct interpretation step that would normally transpire in
> a static_cast. The result of accessing this pointer in any way is then UB.
>
> If you're using MI you are GOING to have problems here. Otherwise you
> may or may not.
>
> I solve this problem in our shop by disallowing the passing of variables
> through a void* without a type-safe wrapper like boost::any. This makes
> sure that the pointers on both sides of the cast will be the exact same
> type, as they must be to avoid UB.
Just to be clear, none of the variables are ever passing through a
void*.
The only use of a void* in the sample code is to pass around a pointer
to a function. In every case, the function is always successfully
passed and called.
Again, it is unlikely the usage of the void* in the code is the cause
of this problem.
Any other suggestions people have are always appreciated.