[expr.dynamic.cast]

# 7 Expressions [[expr]](./#expr)

## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.dynamic.cast)

### 7.6.1 Postfix expressions [[expr.post]](expr.post#expr.dynamic.cast)

#### 7.6.1.7 Dynamic cast [expr.dynamic.cast]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4409)

The result of the expression dynamic_cast<T>(v) is the result of
converting the expression v to type T[.](#1.sentence-1)

T shall be a pointer or reference to a complete class type, or
âpointer to cv voidâ[.](#1.sentence-2)

The dynamic_cast operator shall not cast
away constness ([[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast"))[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4419)

If T is a pointer type, v shall be a prvalue of a
pointer to complete class type, and the result is a prvalue of typeT[.](#2.sentence-1)

If T is an lvalue reference type, v shall be
an lvalue of a complete class type, and the result is an lvalue of the
type referred to by T[.](#2.sentence-2)

If T is an rvalue reference type,v shall be a glvalue having a complete class type, and the
result is an xvalue of the type referred to by T[.](#2.sentence-3)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4428)

If the type of v is the same as T (ignoring cv-qualifications),
the result isv (converted if necessary)[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4433)

If T is âpointer to *cv1* Bâ and v has
type âpointer to *cv2* Dâ such that B is a base
class of D, the result is a pointer to the unique B subobject of the D object pointed to by v, or
a null pointer value if v is a null pointer value[.](#4.sentence-1)

Similarly, ifT is âreference to *cv1* Bâ and v has
type *cv2* D such that B is a base class ofD, the result is the unique B subobject of the D object referred to by v[.](#4.sentence-2)[51](#footnote-51 "The most derived object ([intro.object]) pointed or referred to by v can contain other B objects as base classes, but these are ignored.")

In both the pointer and
reference cases, the program is ill-formed if B is an inaccessible or
ambiguous base class of D[.](#4.sentence-3)

[*Example [1](#example-1)*: struct B { };struct D : B { };void foo(D* dp) { B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp;} â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4463)

Otherwise, v shall be a pointer to or a glvalue of a[polymorphic type](class.virtual#def:class,polymorphic "11.7.3 Virtual functions [class.virtual]")[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4467)

If v is a null pointer value, the result is a null pointer value[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4470)

If v has type âpointer to cv Uâ andv does not point to an object
whose type is similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to U and
that is
within its lifetime or
within its period of construction or destruction ([[class.cdtor]](class.cdtor "11.9.5 Construction and destruction")),
the behavior is undefined[.](#7.sentence-1)

If v is a glvalue of type U andv does not refer to an object
whose type is similar to U and
that is
within its lifetime or
within its period of construction or destruction,
the behavior is undefined[.](#7.sentence-2)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4486)

If T is âpointer to cv voidâ, then the result
is a pointer to the most derived object pointed to by v[.](#8.sentence-1)

Otherwise, a runtime check is applied to see if the object pointed or
referred to by v can be converted to the type pointed or
referred to by T[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4493)

Let C be the class type to which T points or refers[.](#9.sentence-1)

The runtime
check logically executes as follows:

- [(9.1)](#9.1)

  If, in the most derived object pointed (referred) to by v,v points (refers) to a public base class subobject of aC object, and if only one object of type C is derived
from the subobject pointed (referred) to by v,
the result points (refers) to that C object[.](#9.1.sentence-1)

- [(9.2)](#9.2)

  Otherwise, if v points (refers) to a public base
class subobject of the most derived object, and the type of the most
derived object has a base class, of type C, that is unambiguous
and public, the result points (refers) to theC subobject of the most derived object[.](#9.2.sentence-1)

- [(9.3)](#9.3)

  Otherwise, the
runtime check [*fails*](#def:fails)[.](#9.3.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4513)

The value of a failed cast to pointer type is the null pointer value of
the required result type[.](#10.sentence-1)

A failed cast to reference type [throws
an exception](except.throw "14.2 Throwing an exception [except.throw]") of a type that would match a[handler](except.handle "14.4 Handling an exception [except.handle]") of type [std​::​bad_cast](bad.cast "17.7.4 Class bad_­cast [bad.cast]")[.](#10.sentence-2)

[*Example [2](#example-2)*: class A { virtual void f(); };class B { virtual void g(); };class D : public virtual A, private B { };void g() { D d;
 B* bp = (B*)&d; // cast needed to break protection A* ap = &d; // public derivation, no cast needed D& dr = dynamic_cast<D&>(*bp); // fails ap = dynamic_cast<A*>(bp); // fails bp = dynamic_cast<B*>(ap); // fails ap = dynamic_cast<A*>(&d); // succeeds bp = dynamic_cast<B*>(&d); // ill-formed (not a runtime check)}class E : public D, public B { };class F : public E, public D { };void h() { F f;
 A* ap = &f; // succeeds: finds unique A D* dp = dynamic_cast<D*>(ap); // fails: yields null; f has two D subobjects E* ep = (E*)ap; // error: cast from virtual base E* ep1 = dynamic_cast<E*>(ap); // succeeds} â *end example*]

[*Note [1](#note-1)*:

Subclause [[class.cdtor]](class.cdtor "11.9.5 Construction and destruction") describes the behavior of a dynamic_cast applied to an object under construction or destruction[.](#10.sentence-3)

â *end note*]

[51)](#footnote-51)[51)](#footnoteref-51)

The most derived
object ([[intro.object]](intro.object "6.8.2 Object model")) pointed or referred to byv can contain other B objects as base classes, but these
are ignored[.](#footnote-51.sentence-1)
