Date: Mon, 19 Aug 2019 23:16:34 +0300
On 19/08/2019 22:57, Brian Bi wrote:
> On Mon, Aug 19, 2019 at 2:15 PM <language.lawyer_at_[hidden]> wrote:
>
>> On 19/08/2019 19:33, Brian Bi wrote:
>>> On Sat, Aug 17, 2019 at 2:16 PM Language Lawyer via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> std::bless<std::byte[sizeof(T)]> (or how it is currently named), when it
>>>> is added to the standard, will kinda allow accessing object
>> representation
>>>> without introducing very non-trivial changes to the C++ memory and
>> object
>>>> model.
>>>
>>> If I understand the std::bless approach properly, it has a serious
>>> shortcoming: let's say T has some sufficiently nontrivial class type.
>> Then,
>>> the call to std::bless followed by reading from the std::byte array will
>>> create the std::byte array, which *ends the lifetime of the *T since the
>> T's
>>> storage has now been reused by the std::byte array. If T is not an
>>> implicit-lifetime type, then that means if you still want to use the
>>> original T value *qua* T, then tough luck. If the T object had automatic
>>> storage duration and a nontrivial destructor, then UB will happen when it
>>> goes out of scope.
>>
>> Right, you'll need to recreate an object of type T using std::bless<T>
>> when you're done accessing the array.
>> (Note that you'll have to do this even if T is an implicit-lifetime type!)
>>
>
> I think if T is an implicit-lifetime type, the std::bless<std::byte[N]>
> call can implicitly create the array first, and then implicitly create the T
> object as well (so the array provides storage for the T object, and both
> now coexist).
The creation of an object of type T would end the lifetime of the array elements, so accessing them would be UB.
> But if T is not an implicit-lifetime type, then calling std::bless<T>
> afterward won't work.
I should have said this in the beginning: I don't think accessing the representation of objects of not implicit-lifetime type makes sense (maybe T should be even more constrained than implicit-lifetime type).
So this is not an issue.
> Plus, even if T *is* an implicit-lifetime type, the idea that you have to
> destroy and recreate the object in order to observe its object
> representation seems untenable. What happens if T contains a const member?
> Now everyone who had access to that T object has to launder their pointers,
> just because someone wanted to observe the object representation.
This just shows that the access to object representations do not fit well into the current model of the C++ abstract machine.
>>
>> I do not think that this is a good way.
>>
>
> What problem did this cause when it was effectively the status quo in
> C++14, that is so serious that we should not attempt to codify it in C++23
> or some future version of the standard?
I do not think calling bytes of memory "objects" is a good status quo.
> On Mon, Aug 19, 2019 at 2:15 PM <language.lawyer_at_[hidden]> wrote:
>
>> On 19/08/2019 19:33, Brian Bi wrote:
>>> On Sat, Aug 17, 2019 at 2:16 PM Language Lawyer via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> std::bless<std::byte[sizeof(T)]> (or how it is currently named), when it
>>>> is added to the standard, will kinda allow accessing object
>> representation
>>>> without introducing very non-trivial changes to the C++ memory and
>> object
>>>> model.
>>>
>>> If I understand the std::bless approach properly, it has a serious
>>> shortcoming: let's say T has some sufficiently nontrivial class type.
>> Then,
>>> the call to std::bless followed by reading from the std::byte array will
>>> create the std::byte array, which *ends the lifetime of the *T since the
>> T's
>>> storage has now been reused by the std::byte array. If T is not an
>>> implicit-lifetime type, then that means if you still want to use the
>>> original T value *qua* T, then tough luck. If the T object had automatic
>>> storage duration and a nontrivial destructor, then UB will happen when it
>>> goes out of scope.
>>
>> Right, you'll need to recreate an object of type T using std::bless<T>
>> when you're done accessing the array.
>> (Note that you'll have to do this even if T is an implicit-lifetime type!)
>>
>
> I think if T is an implicit-lifetime type, the std::bless<std::byte[N]>
> call can implicitly create the array first, and then implicitly create the T
> object as well (so the array provides storage for the T object, and both
> now coexist).
The creation of an object of type T would end the lifetime of the array elements, so accessing them would be UB.
> But if T is not an implicit-lifetime type, then calling std::bless<T>
> afterward won't work.
I should have said this in the beginning: I don't think accessing the representation of objects of not implicit-lifetime type makes sense (maybe T should be even more constrained than implicit-lifetime type).
So this is not an issue.
> Plus, even if T *is* an implicit-lifetime type, the idea that you have to
> destroy and recreate the object in order to observe its object
> representation seems untenable. What happens if T contains a const member?
> Now everyone who had access to that T object has to launder their pointers,
> just because someone wanted to observe the object representation.
This just shows that the access to object representations do not fit well into the current model of the C++ abstract machine.
>>
>> I do not think that this is a good way.
>>
>
> What problem did this cause when it was effectively the status quo in
> C++14, that is so serious that we should not attempt to codify it in C++23
> or some future version of the standard?
I do not think calling bytes of memory "objects" is a good status quo.
Received on 2019-08-19 15:18:39