Date: Thu, 9 Sep 2021 19:21:11 +0200
If you use the reference solely as the left Hand side of an assignment of a
trivial type you are fine. In all other cases you are not.
Passing it into construct_at is invalid as that is not an assignment.
D'Alessandro, Luke K <ldalessa_at_[hidden]> schrieb am Do., 9. Sept. 2021, 17:11:
>
>
> On Sep 9, 2021, at 12:02 AM, Michael Schellenberger Costa via
> Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> This message was sent from a non-IU address. Please exercise caution when
> clicking links or opening attachments from external sources.
>
> Am Do., 9. Sept. 2021 um 06:59 Uhr schrieb Jason McKesson via
> Std-Proposals <std-proposals_at_[hidden]>:
>
>> On Wed, Sep 8, 2021 at 2:29 PM D'Alessandro, Luke K via Std-Proposals
>> <std-proposals_at_[hidden]> wrote:
>> >
>> >
>> > I guess I have two questions:
>> >
>> > 1. Does std::construct_at change the active member of a union?
>>
>> As stated in [class.union]/2, "a non-static data member is active if
>> its name refers to an object whose lifetime has begun and has not
>> ended." `construct_at` can begin the lifetime of objects (which can
>> also cause the lifetime of other overlapping objects to end).
>>
>> Therefore, it can change the active union member.
>>
>
> While `std::construct_at` does indeed begin the lifetime of the element it
> constructs, the lifetime of the array has not begun. Therefore, forming a
> reference to an object outside of its lifetime is UB, so `&u.data[1]` is
> not possible. We had the exact same issue recently when implementing
> constexpr std::string for MSVC STL. There we have an indirection to
> `char_traits` and would need to call `char_traits::assign(&sso_storage[0],
> CharType())` which again is invalid due to forming of the reference to
> `sso_storage[0]` outside of its lifetime
>
> If you have a non-assignable class then the best way around is an
> `
> if constexpr(std::is_assignable_v) {
> // change the active member of the union to the array here.
> }
> std::construct_at(...)
>
>
>
> Thanks Michael,
>
> My only confusion is the statement that `&u.data[1]` is a problem is that
> https://eel.is/c++draft/class.union#general-example-2 seems to do exactly
> that.
>
> Just so I understand in the future, is the example okay because it doesn’t
> apply `&` or is it okay because it’s part of the statement that is actually
> starting the lifetime?
>
> Luke
>
> `
>
> Cheers
> Michael
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
>
trivial type you are fine. In all other cases you are not.
Passing it into construct_at is invalid as that is not an assignment.
D'Alessandro, Luke K <ldalessa_at_[hidden]> schrieb am Do., 9. Sept. 2021, 17:11:
>
>
> On Sep 9, 2021, at 12:02 AM, Michael Schellenberger Costa via
> Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> This message was sent from a non-IU address. Please exercise caution when
> clicking links or opening attachments from external sources.
>
> Am Do., 9. Sept. 2021 um 06:59 Uhr schrieb Jason McKesson via
> Std-Proposals <std-proposals_at_[hidden]>:
>
>> On Wed, Sep 8, 2021 at 2:29 PM D'Alessandro, Luke K via Std-Proposals
>> <std-proposals_at_[hidden]> wrote:
>> >
>> >
>> > I guess I have two questions:
>> >
>> > 1. Does std::construct_at change the active member of a union?
>>
>> As stated in [class.union]/2, "a non-static data member is active if
>> its name refers to an object whose lifetime has begun and has not
>> ended." `construct_at` can begin the lifetime of objects (which can
>> also cause the lifetime of other overlapping objects to end).
>>
>> Therefore, it can change the active union member.
>>
>
> While `std::construct_at` does indeed begin the lifetime of the element it
> constructs, the lifetime of the array has not begun. Therefore, forming a
> reference to an object outside of its lifetime is UB, so `&u.data[1]` is
> not possible. We had the exact same issue recently when implementing
> constexpr std::string for MSVC STL. There we have an indirection to
> `char_traits` and would need to call `char_traits::assign(&sso_storage[0],
> CharType())` which again is invalid due to forming of the reference to
> `sso_storage[0]` outside of its lifetime
>
> If you have a non-assignable class then the best way around is an
> `
> if constexpr(std::is_assignable_v) {
> // change the active member of the union to the array here.
> }
> std::construct_at(...)
>
>
>
> Thanks Michael,
>
> My only confusion is the statement that `&u.data[1]` is a problem is that
> https://eel.is/c++draft/class.union#general-example-2 seems to do exactly
> that.
>
> Just so I understand in the future, is the example okay because it doesn’t
> apply `&` or is it okay because it’s part of the statement that is actually
> starting the lifetime?
>
> Luke
>
> `
>
> Cheers
> Michael
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
>
Received on 2021-09-09 12:21:28