This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-28


2822. Side-effect-free pointer zap

Section: 6.7.5.1  [basic.stc.general]     Status: DR     Submitter: Davis Herring     Date: 2023-11-06

[Accepted as a DR at the March, 2024 meeting.]

Subclause 6.7.5.1 [basic.stc.general] paragraph 4 seems to suggest that the end of duration of a region of storage causes actual modifications to pointer objects, causing questions about data races (in the abstract machine).

Proposed resolution (approved by CWG 2024-03-20):

  1. Append to 6.7.5.1 [basic.stc.general] paragraph 1:

    [ Note: After the duration of a region of storage has ended, the use of pointers to that region of storage is limited (6.8.4 [basic.compound]). -- end note ]
  2. Remove 6.7.5.1 [basic.stc.general] paragraph 4 as follows:

    When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values (6.8.4 [basic.compound]). Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior. [ Footnote: ... ]
  3. Change in 6.8.4 [basic.compound] paragraph 3 as follows:

    [Note 2: A pointer past the end of an object (7.6.6 [expr.add]) is not considered to point to an unrelated object of the object's type, even if the unrelated object is located at that address. A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see 6.7.5 [basic.stc].end note]
  4. Insert a new paragraph after 6.8.4 [basic.compound] paragraph 3:

    A pointer value P is valid in the context of an evaluation E if P is a null pointer value, or if it is a pointer to or past the end of an object O and E happens before the end of the duration of the region of storage for O. If a pointer value P is used in an evaluation E and P is not valid in the context of E, then the behavior is undefined if E is an indirection (7.6.2.2 [expr.unary.op]) or an invocation of a deallocation function (6.7.5.5.3 [basic.stc.dynamic.deallocation]), and implementation-defined otherwise. [ Footnote: Some implementations might define that copying such a pointer value causes a system-generated runtime fault. -- end footnote ] [ Note: P can be valid in the context of E even if it points to a type unrelated to that of O or if O is not within its lifetime, although further restrictions apply to such pointer values (6.7.3 [basic.life], 7.2.1 [basic.lval], 7.6.6 [expr.add]). —end note]
  5. Change in 7.6.1.9 [expr.static.cast] paragraph 14 as follows:

    ... If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value (6.8.4 [basic.compound]) is unspecified. ...
  6. Change in 7.6.1.10 [expr.reinterpret.cast] paragraph 5 as follows:

    A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value (6.8.4 [basic.compound]); mappings between pointers and integers are otherwise implementation-defined.