The C++ Standard define the concept "dynamic type" of a glvalue as follows:
dynamic type
<glvalue> type of the most derived object (1.8) to which the glvalue denoted by a glvalue expression refers [Example: if a pointer (8.3.1) p whose static type is “pointer to class B” is pointing to an object of class D, derived from B (Clause 10), the dynamic type of the expression *p is “D.” References (8.3.2) are treated similarly. —end example ]
How is this definition interpreted if what the glvalue refers to is not the most derived object? Does it mean "type of the most derived object that contains the object to which the glvalue denoted by a glvalue expression refers"?
Another puzzle is about the 4th paragraph in 5.7 of the C++ Standard:
... If the pointer operand points to an element of an array object, ...
I want to ask whether this condition holds if the pointer operand points to a subobject of an element of an array object. As an example, if it does not hold, then the behavior in the following code is undefined, right?
D d[10];
B *p = d; //B is a base class of D
p += 2; //undefined behavior?
The wording is clear. The most derived object is implied to be a complete object, a data member or an array element, i.e. it is not a base class subobject.
WG21/N4527
1.8 The C++ object model [intro.object]
2 Objects can contain other objects, called subobjects. A subobject can be a member subobject (9.2), a base class subobject (Clause 10), or an array element. An object that is not a subobject of any other object is called a complete object.
3 For every object
x
, there is some object called the complete object ofx
, determined as follows:(3.1) — If
x
is a complete object, thenx
is the complete object ofx
.(3.2) — Otherwise, the complete object of
x
is the complete object of the (unique) object that containsx
.4 If a complete object, a data member (9.2), or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject; an object of a most derived class type or of a non-class type is called a most derived object.
D d[10];
B *p = d; //B is a base class of D
p += 2; //undefined behavior?
This has undefined behavior, undoubtedly. There are no additional rules about derived classes. And since every operand of the expression p += 2
is prvalue, no dynamic types of glvalues are concerned.
Edit: Note that dynamic types of prvalues are same as their static types.