0

I have written a code which uses dynamic_cast operator for casting the base class pointer which points the derived class object. But I have a doubt regarding the casting process. First have a look at the source code and the output.

CODE

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void BasePrint(void)
    {
        cout << "This is base print\n";
    }
};

class Derived1 : public Base
{
public:
    void Derived1print(void)
    {
        cout << "This is derived1 print\n";
    }
};

class Derived2 : public Base
{
public:
    void Derived2print(void)
    {
        cout << "This is derived2 print\n";
    }
};

int main(void)
{
    Base *ptr = new Derived1;

    Derived1 *caster1 = dynamic_cast<Derived1 *>(ptr);
    if (caster1 != NULL)
        caster1->Derived1print();

    Derived2 *caster2 = dynamic_cast<Derived2 *>(ptr);
    if (caster2 == NULL) // Doubt in this line
        caster2->Derived2print();
    return 0;
}

OUTPUT

This is derived1 print
This is derived2 print

As in line number 40 it is written that if (caster2 == NULL) then only run this line caster2->Derived2print(); and the output is visible in the terminal!
Now if the caster2 pointer is NULL then how it can be dereferenced using the arrow operator -> to show the output of the Derived2print() method?

  • 3
    This question has, in fact, already been [asked](https://stackoverflow.com/questions/2505328/calling-class-method-through-null-class-pointer)--the inheritance ultimately has nothing to do with it, everything boils down to the fact that you're trying to invoke a class method from a null pointer. Pay particular attention to the fact that this is _undefined behavior_, so any result is considered acceptable from the perspective of the C++ standard. That includes "terminate the program", but it also includes "do nothing" and "call the method as though you had a valid pointer" – Nathan Pierson Jul 25 '21 at 17:21
  • *"this question is of inheritance and `dynamic_cast`"* -- not really. You use inheritance and `dynamic_cast` as a convoluted way to make `caster2` null, but otherwise they have no bearing on the question in its current form. Did you leave out something relevant that would change my assessment? – JaMiT Jul 26 '21 at 00:48
  • *"if the pointer is null, then how it is dereferenced with making the program to crash (as it would have ideally be done if we dereference a pointer initialized as `int * ptr = NULL`."* -- it is tough to predict undefined behavior; a crash is never guaranteed by the C++ standard. In fact, when I changed the initialization of `caster2` to what you suggested (`Derived2 *caster2 = nullptr;`), I got the same result as with your unaltered code. *(On the other hand, when I changed the functions in the derived classes to override the virtual function, I did get a crash with either initialization.)* – JaMiT Jul 26 '21 at 00:54
  • As long as your setup does not involve overriding the virtual function, I propose it is a duplicate of [What will happen when I call a member function on a NULL object pointer?](https://stackoverflow.com/questions/2533476/what-will-happen-when-i-call-a-member-function-on-a-null-object-pointer) (For the naysayers: I am aware that overriding the virtual function will not eliminate the undefined behavior. However, I would consider that a significant enough detail for this to be considered a distinct question; enough for me personally to not vote to close as a duplicate.) – JaMiT Jul 26 '21 at 00:58

1 Answers1

3

The tl;dr; is "undefined behavior"

As soon as your code dereferences a null pointer all bets are off. In this case the compiler is assuming the null pointer points to a valid object of it's static type and directly calling it's implementation of the [edit: non] virtual method.

BCS
  • 75,627
  • 68
  • 187
  • 294
  • `Derived2print(void)` is not virtual. – Jeffrey Jul 25 '21 at 16:40
  • @Jeffrey ok. But the same reasoning applies in both cases. – BCS Jul 25 '21 at 21:01
  • I agree OP was invoking UB, per the standard. But in order to answer why it worked (even though it might not), the fact that the function was non-virtual IS important. Thanks for the edit. – Jeffrey Jul 25 '21 at 21:19
  • It's actually possible that it would also work with a virtual method, if the compiler convinces it self that there can't be an override. In that case it could de-visualize the call and revert to the case that was actual asked about. – BCS Jul 26 '21 at 00:23