Skip to content

[basic.life] Unclear distinction between reused and released (for storage) #888

@safocl

Description

@safocl

Full name of submitter (unless configured in github; will be published with the issue): Safocl Stollmannovic

Reference (section label): p2.5

The lifetime of an object o of type T ends when:
(2.5) the storage which the object occupies is released, or is reused by an object that is not nested within o ([intro.object]).

Link to reflector thread (if any): #884 (comment) (and below), #885

Issue description:
It's not clear in which cases storage is reused and when it's released. In my opinion, it's perfectly clear when storage is deallocated (release) (the scope in which the storage was created has ended) and when another object is created within the storage in a portion of bytes previously occupied by an object (reuse).
However, this distinction isn't clear when the lifetime of the byte array that provides the storage for an object expires.
1.

alignas(int) unsigned char buffer[8];

int main() {
    auto ptr_int = new (buffer) int{};
    auto ptr_char = new (buffer) char{}; // #1 storage for `int` was reused
    auto storage_ptr = new (&buffer) unsigned char[8]; // #2 storage for `char` was released?
}
#include <print>

struct alignas(int) S{
    unsigned char s[sizeof(int)];
    S(){std::println("S()");}
    ~S(){std::println("~S()");}
};

int main(){
    S s{}; // #1
    auto int_ptr = new(s.s) int{42}; // #2
    std::println("int = {}", *int_ptr); // #3
    s.~S(); // #4
    // std::println("int = {}", *int_ptr); // #5
    new(&s) S{};
}

What's going on in line #4? Is this where the storage release occurs? In line #5, we can't correctly access the data through the int_ptr pointer (for what reason)?

It's also unclear from this: if the lifetime of a byte array ends, then the objects nested within it that aren't elements of the array also end their lifetimes? (If such an action triggers a storage release, then the lifetime of such nested objects ends accordingly, as I expect.)

[intro.object#4]

4 An object a is nested within another object b if
(4.1) a is a subobject of b, or
(4.2) b provides storage for a, or
(4.3) there exists an object c where a is nested within c, and c is nested within b.

Suggested resolution:
Perhaps we should explicitly describe when storage is reused and when it is released? (Or introduce appropriate descriptions for "storage release" and "storage reuse")

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