views:

392

answers:

4

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?

+3  A: 

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.

Kim Gräsman
But why can't the exception be thrown in case of pointers also?
Naveen
You would then have to try-catch every dynamic_cast which is dirty code. Instead you can take the address, dynamic_cast it and check for null.
sharptooth
Also, throwing and catching exceptions is relatively expensive, and I suspect the designers wanted to find a way to minimize that cost.
Kim Gräsman
+12  A: 

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.

sharptooth
+4  A: 

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).

AProgrammer
+4  A: 

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.

anon