Title
Conversions applied to out-of-lifetime non-POD lvalues
Status
cd3
Section
6.7.3 [basic.life]
Submitter
Mike Miller

Created on 2006-09-27.00:00:00 last changed 123 months ago

Messages

Date: 2012-02-15.00:00:00

[Voted into the WP at the February, 2012 meeting; moved to DR at the October, 2012 meeting.]

Date: 2008-03-15.00:00:00

Proposed resolution (March, 2008):

  1. Change 6.7.3 [basic.life] paragraph 5 as follows:

  2. ...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, or

    • the pointer is used as the operand of a static_cast (7.6.1.9 [expr.static.cast]) (except when the conversion is to void*, 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, or

    • the pointer is used as the operand of a dynamic_cast (7.6.1.7 [expr.dynamic.cast])...

  3. Change 6.7.3 [basic.life] paragraph 6 as follows:

  4. ...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 class type (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&, 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.

[Drafting notes: Paragraph 5 was changed to track the changes to paragraph 6. See also the resolution for issue 658.]

Date: 2006-09-27.00:00:00

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.3 [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)?

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2012-11-03 00:00:00adminsetstatus: dr -> drwp
2012-02-27 00:00:00adminsetmessages: + msg3789
2012-02-27 00:00:00adminsetstatus: ready -> dr
2011-09-06 00:00:00adminsetstatus: review -> ready
2008-05-18 00:00:00adminsetmessages: + msg1648
2008-05-18 00:00:00adminsetstatus: drafting -> review
2007-10-09 00:00:00adminsetstatus: open -> drafting
2006-09-27 00:00:00admincreate