Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret the reachability requirement of std::launder?

The std::launder function requires that every byte that would be reachable through the result is reachable through the argument. "Reachable" is defined as follows:

A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element.

According to an answer to another question, this restriction "... means that you cannot use launder to obtain a pointer that would allow you to access more bytes than the source pointer value allows, on pain of undefined behavior."

This makes sense for the examples given by T.C. but I don't understand how to interpret it in the case where the original object has been replaced by a new object, which is the original purpose contemplated for std::launder. The standard has the following example:

struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5}; // p does not point to new object (6.8) because X::n is const
const int b = p->n; // undefined behavior
const int c = std::launder(p)->n; // OK

In this case, by the time std::launder is called, the object pointed to by p---the original X object---has already ceased to exist since the creation of a new object in the storage it occupied has implicitly ended its lifetime ([basic.life]/1.4). Therefore, it seems that there are no bytes reachable through p since p does not point to any object Y. This is obviously not the intended reading since it would make the call to std::launder undefined behaviour in the example.

  1. Have I misunderstood the wording here, or is the wording defective?
  2. What is the intended meaning, which would make the example valid?
like image 597
Brian Bi Avatar asked Aug 12 '19 17:08

Brian Bi


1 Answers

Just going by the example, the relevant text is (Bold is mine):

A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y

Due to the placement new, the pointer value now points to the "newly placed" object, and hence the reachability is of that.

I would say that is clear enough as it stands.

like image 179
darune Avatar answered Oct 24 '22 00:10

darune