This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Voted into the WP at the February, 2012 meeting; moved to DR at the October, 2012 meeting.]
An lvalue referring to an out-of-lifetime non-POD class objects can be used in limited ways, subject to the restrictions in 6.7.4 [basic.life] paragraph 6:
if the original object will be or was of a non-POD class type, the program has undefined behavior if:
the lvalue is used to access a non-static data member or call a non-static member function of the object, or
the lvalue is implicitly converted (7.3.12 [conv.ptr]) to a reference to a base class type, or
the lvalue is used as the operand of a static_cast (7.6.1.9 [expr.static.cast]) except when the conversion is ultimately to cv char& or cv unsigned char& ), or
the lvalue is used as the operand of a dynamic_cast (7.6.1.7 [expr.dynamic.cast]) or as the operand of typeid.
There are at least a couple of questionable things in this list. First, there is no “implicit conversion to a reference to a base class,” as assumed by the second bullet. Presumably this is intended to say that the lvalue is bound to a reference to a base class, and the cross-reference should be to 9.4.4 [dcl.init.ref], not to 7.3.12 [conv.ptr] (which deals with pointer conversions). However, even given that adjustment, it is not clear why it is forbidden to bind a reference to a non-virtual base class of an out-of-lifetime object, as that is just an address offset calculation. (Binding to a virtual base, of course, would require access to the value of the object and thus cannot be done outside the object's lifetime.)
The third bullet also appears questionable. It's not clear why static_cast is discussed at all here, as the only permissible static_cast conversions involving reference types and non-POD classes are to references to base or derived classes and to the same type, modulo cv-qualification; if implicit “conversion” to a base class reference is forbidden in the second bullet, why would an explicit conversion be permitted in the third? Was this intended to refer to reinterpret_cast? Also, is there a reason to allow char types but disallow array-of-char types (which are more likely to be useful than a single char)?
Proposed resolution (March, 2008):
Change 6.7.4 [basic.life] paragraph 5 as follows:
...If the object will be or was of a non-trivial class type, the program has undefined behavior if:
the pointer is used to access a non-static data member or call a non-static member function of the object, or
the pointer is implicitly converted (7.3.12 [conv.ptr]) to a pointer to a virtual base class
type, orthe pointer is used as the operand of a static_cast (7.6.1.9 [expr.static.cast])
(except when the conversion is tovoid*, or to void* and subsequently to char*, or unsigned char*).pointer to cv void, or to pointer to cv void and subsequently to pointer to cv char or pointer to cv unsigned char, orthe pointer is used as the operand of a dynamic_cast (7.6.1.7 [expr.dynamic.cast])...
Change 6.7.4 [basic.life] paragraph 6 as follows:
...if the original object will be or was of a non-trivial class type, the program has undefined behavior if:
the lvalue is used to access a non-static data member or call a non-static member function of the object, or
the lvalue is
implicitly converted (7.3.12 [conv.ptr])bound to a reference to a virtual base classtype(9.4.4 [dcl.init.ref]), or
the lvalue is used as the operand of a static_cast (7.6.1.9 [expr.static.cast]) except when the conversion is ultimately to cv char& or cv unsigned char&, orthe lvalue is used as the operand of a dynamic_cast (7.6.1.7 [expr.dynamic.cast]) or as the operand of typeid.
[Drafting notes: Paragraph 5 was changed to track the changes to paragraph 6. See also the resolution for issue 658.]