Difference in behavior while using dynamic_cast with reference and pointers

C++CastingDynamic Cast

C++ Problem Overview


I was checking the behavior of dynamic_cast and found that when it fails, std::bad_cast exception is thrown only if the destination is a reference type. If the destination is a pointer type then no exception is thrown from the cast. This is my sample code:

class A
{
	public:
		virtual ~A()
		{
		}
};

class B : public A
{
};

int  main()
{
    A* p = new A;
    
    //Using reference
    try
    {
	B& b = dynamic_cast<B&>(*p);
    }
    catch(std::bad_cast exp)
    {
	std::cout<<"Caught bad cast\n";
    }
    
    //Using pointer
      try
    {
	B* pB = dynamic_cast<B*>(p);
	
	if( pB == NULL)
	{
		std::cout<<"NULL Pointer\n";
	}
    }
    catch(std::bad_cast exp)
    {
	std::cout<<"Caught bad cast\n";
    }
    
    return 0;
}

Output is "Caught bad cast" and "NULL pointer". Code is compiled using VS2008. Is this the correct behavior ? If yes, then why there is a difference?

C++ Solutions


Solution 1 - C++

Yes, this is correct behaviour. The reason is that you can have a null pointer, but not a null reference - any reference has to be bound to an object.

So when dynamic_cast for a pointer type fails it returns a null pointer and the caller can check for that, but when it fails for a reference type it can't return a null reference, so an exception is the only reasonable way to signal a problem.

Solution 2 - C++

See the C++ Standard, section 5.2.7/9:

> 9 The value of a failed cast to > pointer type is the null pointer value > of the required result type. A failed > cast to reference type throws bad_cast > (18.5.2).

As to why - these are Stroustrup's words from the D & E book, section 14.2.2:

> I use a reference cast when I want an > assumption about a reference type > checked and consider it a failure for > my assumption to be wrong. If instead > I want to select among plausible > alternatives, I use a pointer cast and > test the result.

Solution 3 - C++

Yes, 5.2.7/9

> The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws bad_cast (18.5.2).

Solution 4 - C++

Yes, it is. Because dynamic_cast can't return NULL for a failed reference cast, an exception is the only way out.

That is, a reference can't be NULL, so there is nothing suitable to return.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNaveenView Question on Stackoverflow
Solution 1 - C++sharptoothView Answer on Stackoverflow
Solution 2 - C++anonView Answer on Stackoverflow
Solution 3 - C++AProgrammerView Answer on Stackoverflow
Solution 4 - C++Kim GräsmanView Answer on Stackoverflow