Incorrect cast – is it the cast or the use which is undefined behavior

  • A+
Category:Languages

If I do a cast from a Base to a Derived type, but the Base type isn't an instance of derived type, but only use the result if it is, do I get undefined behaviour?

Hard to understand what I'm asking? take a look at this example:

struct Animal { int GetType(){...} }; struct Dog : Animal { bool HasLoudBark(){...}}; struct Cat : Animal { bool HasEvilStare(){...} };  Animal * a = ...; Dog* d = static_cast<Dog*>(a);  if(a->GetType() == DogType && d->HasLoudBark())     .... 

In this case a may or not be a Dog. We always do the static_cast of a to Dog * d but we never use d unless we're sure its a Dog.

Assuming that a is not a Dog, is this undefined behaviour at the point of the cast? Or is it defined as we don't actually use d unless it is really is a Dog?

References to the relevant parts of the standard are appreciated.

(Yes I know I can use dynamic_cast, and RTTI, and probably this isn't great code, but I'm more interested in whether this is valid)


The cast itself has undefined behaviour. Quoting C++17 (n4659) [expr.static.cast] 8.2.10/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 class derived (Clause 13) from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. ... If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: