dynamic_cast does not work as specified



Here's a problem I hit that is inconsistent with the documentation.

I'm handling an OnUpdate notification, where the CObject* can be one of several types
depending on the value of lHint.

So the code is basically

void CMyView::OnUpdate(CView * pSender, LPARAM lHint, CObject *pHint)
{
if(lHint == 0 && pHint == NULL)
{ /* normal update */
CView::OnUpdate(pSender, lHint, pHint);
return;
} /* normal update */

if(lHint == WHATEVER)
{ /* update the whatever */
SubThing * p = dynamic_cast<SubThing *>pHint;
ASSERT(p != NULL);
if(p != NULL)
DoSomething(p);
} /* update the whatever */
} // CMyView::OnUpdate

where I have defined

class Thing { ... };
class SubThing : public Thing { ... };

If I try to single-step into it, it tries to trace a source file along some bizarre path
for rtti.cpp, but this source is not included in the distribution. Bummer.

So, I thought, it might have to do with the fact that (due to exceptionally poor design
decisions in the original MFC design) the pHint is declared to be a CObject*, unrelated to
a Thing or SubThing (in a rational world, it would have been an LPVOID). The line

SubThing * p = dynamic_cast<SubThing *>pHint;

generates the compile-time diagnostic:
C2681: 'CObject *': invalid expression type for dynamic_cast

I have no idea why this is an invalid expression for dynamic_cast. But it may deal with
some obscure, undocumented rule.

But dynamic_cast is defined to work on, among other expressions, a pointer-to-void, so I
tried

LPVOID ptr = (LPVOID)pHint;
SubThing * p = dynamic_cast<SubThing *>p;

but that produces an error
C2681: 'LPVOID': invalid expression type for dynamic_cast

in spite of the documetnation of dynamic_cast, which *clearly* states:

The type-id must be a pointer or a reference to a previously defined class type or
a "pointer to void".

It turns out I can get around this by doing

Thing * ptr = (Thing *)pHint;
SubThing * p = dynamic_cast<SubThing *>ptr;

So does this represent an error in the documentation, or an error in the implementation?
joe
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: dynamic_cast does not work as specified
    ... inheritance chain of type-id (yes, I see now that I can cast to a void*; ... then p is a pointer to an object of type SubThing. ... What is interesting is that casting to LPVOID makes it work; ... the horror of OnUpdate/UpdateAllViews using a CObject* instead of an LPVOID. ...
    (microsoft.public.vc.mfc)
  • Re: main function address
    ... the printffunction documentation in ... The fprintf() documentation in 7.19.6.1 says ... The value of the pointer is ... does the implicit conversion apply when the pointer value is extracted ...
    (comp.lang.c)
  • Re: Communication between Views
    ... >modified CObject? ... would I automatically get a pointer to the instance of CObject ... MVP Tips: http://www.flounder.com/mvp_tips.htm ...
    (microsoft.public.vc.mfc)
  • Re: Documentation on implementing a Windows Scripting Engine
    ... that documentation certainly qualifies as private. ... can get access to it if you start working for Microsoft. ... Otherswise a scripting engine is simply a language interpreter. ... Does anyone have a pointer as to a good source of documentation on this ...
    (microsoft.public.win32.programmer.ole)
  • Re: Communication between Views
    ... modified CObject? ... if I'm using a data class encapsulating only data ... would I automatically get a pointer to the instance of CObject ...
    (microsoft.public.vc.mfc)