Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

CWG2822 [basic.stc.general] Side-effect-free pointer zap #457

Copy link
Copy link
Closed
cplusplus/draft
#6906
cplusplus/draft#6906
@opensdh

Description

@opensdh
Issue body actions

Reference (section label): [basic.stc.general]

Link to reflector thread (if any): main proposal

Issue description:

[basic.stc.general]/4 seems to suggest that the end of the duration of a region of storage causes modifications to pointer objects, raising questions about data races (in the abstract machine) and complicating ongoing discussions about the compatibility of the standard with certain concurrent algorithms.

Suggested resolution:

Per reflector discussion, separate inherently invalid pointer values (as from reinterpret_cast of arbitrary integers) from circumstantially invalid pointer usage (that does not happen before the destruction of the relevant storage), by making the wording changes below.

Change in [basic.stc.general]/4:

[Note: When After 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 behave as if they were invalid pointer values ([basic.compound]). — end note]

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.[…]

Change in [basic.compound]/3:

[…] Every value of pointer type is one of the following:

  • a pointer to an object or function (the pointer is said to point to the object or function), or
  • a pointer past the end of an object ([expr.add]), or
  • the null pointer value for that type, or
  • an invalid pointer value.

A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object[…] or the first byte in memory after the end of the storage occupied by the object, respectively.

[Note: A pointer past the end of an object ([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 [basic.stc]. — end note]

[…]

Insert a new paragraph after /3, including the deleted text from [basic.stc.general]/4:

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 or an invocation of a deallocation function, and implementation-defined otherwise.[…]

[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 ([basic.lval], [expr.add], [basic.life]). — end note]

For clarity, add cross reference in [expr.static.cast]/14:

A prvalue of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T", where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. 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 ([basic.compound]) is unspecified.

[…]

and similarly in [expr.reinterpret.cast]/5:

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 ([basic.compound]); mappings between pointers and integers are otherwise implementation-defined.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.