Home > Net >  Does this downcasting lead to undefined behavior?
Does this downcasting lead to undefined behavior?

Time:03-17

Given this sample:

  class Base
  {
      public:
      void foo() {}; 
  };

  class Derived : public Base
  {     
  };

  int main()
  {
      Base b;
      Derived* d = static_cast<Derived*>(&b);
      d->foo();
  }

I just have three cases: when void foo():

  • is member of Base,
  • and when it is member of Derived,
  • and when it is member of Base and Derived.

My questions are:

  • Does the member access expression d->foo() is undefined behavior in all three cases?.

  • If the member access expression is UB, Does the only workaround is to use dynamic_cast?

CodePudding user response:

From the C standard §7.6.1.9.11

A prvalue of type “pointer to cv1 B”, where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a complete class derived from B,

...

If the prvalue of type “pointer to cv1 B” points to a B that is actually a base class subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.

So using static_cast to downcast is only valid if you know (via some other means) that the cast is valid. If you take a Base that isn't a Derived and use a static_cast to pretend that it is, you've invoked undefined behavior, even before you try to dereference the pointer. So you could remove the d->foo() line and still have undefined behavior. It's the cast that's bad.

If your goal is to conditionally check whether you've got an instance of a subclass, then you want dynamic_cast.

  • Related