Skip to content

[intro.races] p2 Whether an opaque type reads the same memory location is unclear #884

@xmh0511

Description

@xmh0511

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

[intro.races] p2 says:

Two expression evaluations conflict if one of them

and the other one

  • 2.3 reads or modifies the same memory location or
  • 2.4 starts or ends the lifetime of an object occupying storage that overlaps with the memory location.

The definition of a memory location is

A memory location is the storage occupied by the object representation of either an object of scalar type that is not a bit-field or a maximal sequence of adjacent bit-fields all having nonzero width.

Consider this example:

#include <string>
#include <thread>

alignas(std::string) unsigned char buffer[sizeof(std::string)];
auto ptr = new (buffer) std::string{};

int main() {    
    std::jthread t1([]() {
        new (buffer) char{};  // #1
    });
    std::jthread t2([]() {
        auto r = ptr->size();  // #2
    });
}

In this example, #1 is an evaluation that starts the lifetime of an object in a memory location called L. #2 is an evaluation that reads the string object. In [intro.races] p2, only bullet 2.3 mentions reading a memory location, that is, only 2.3 can apply to #2, therefore, 2.2 applies to #1.

However, std::string is a type whose private members are opaque. We don't know whether a std::string object comprises a scalar member object in the memory location L, such that the read to std::string will read the scalar object, which will conflict with #1.

In addition, consider another example:

#include <thread>

alignas(int) unsigned char buffer[8];

int main() {
    auto ptr = new (buffer) int{};
    std::jthread t1([&]() {
        new (buffer) char{};  // #1
    });
    std::jthread t2([&]() {
        auto n = *ptr;  // #2
    });
}

Similarly, only 2.3 can apply to #2; #1 starts the lifetime of an object of type char in memory location L. However, the size of the object of type int is larger than int. In this case, can we say that reading a larger memory location reads the same memory location as L?

Suggested Resolution:

Change 2.3 bullet to

reads or modifies a memory location that overlaps with the above-mentioned memory location or

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