Trivial copyability and `optiona/variant`.

148 views
Skip to first unread message

Nicol Bolas

unread,
Sep 22, 2016, 3:06:04 PM9/22/16
to ISO C++ Standard - Future Proposals
`optional` is not required to be trivially copyable if `T` is trivially copyable. And yet, I cannot imagine an implementation of `optional` where that is not at least possible. After all, the bit saying whether the `optional` is empty is likely a basic type. So why should trivial copyability not be possible?

Similarly, if all of the `Ts` for a `variant` are trivially copyable, it should be possible to make the variant itself trivially copyable.

Is there an implementation problem I'm not aware of, or was this an oversight? Should a national body comment be filed or a defect report be sent?

Casey Carter

unread,
Sep 22, 2016, 5:46:27 PM9/22/16
to ISO C++ Standard - Future Proposals
Those requirements are implementable: the Microsoft implementations of optional and variant maintain trivial copyability of the contained types. It seems to be QoI to me; I see no strong motivation to *require* that behavior.

Matt Calabrese

unread,
Sep 22, 2016, 6:19:05 PM9/22/16
to ISO C++ Standard - Future Proposals
I mostly agree. I don't think it's a defect, but I do think that requiring triviality is the direction that we should go in a future standard. My main reason for thinking we should require triviality post-c++17 is mostly just because I think having a somewhat-usable constexpr variant is worthwhile. At the moment, due to language restrictions (that I personally consider defects) it is not possible to implement a constexpr copy or move operation for a variant unless the copy/move operation is trivial. So while I think it's useful to be able to guarantee triviality, I think the more important thing is guaranteeing at least some variant instantiations are a reasonable literal type, which in practice ends up requiring the operation to be trivial anyway.

Apart from constexpr, there is at least one other reason to require triviality eventually anyway -- while it is rare, it is sometimes a requirement of niche datastructures to have an element type that is trivially copyable (i.e. certain lockfree datastructures). It would be pretty cool if a standard variant with appropriate parameters (or any algebraic data type for that matter) were guaranteed to meet these requirements.

Ville Voutilainen

unread,
Sep 22, 2016, 6:23:51 PM9/22/16
to ISO C++ Standard - Future Proposals
On 23 September 2016 at 00:46, Casey Carter <cart...@gmail.com> wrote:
> Those requirements are implementable: the Microsoft implementations of
> optional and variant maintain trivial copyability of the contained types. It
> seems to be QoI to me; I see no strong motivation to *require* that
> behavior.


Portability would seem like a fairly good motivation for that to me.

Andrey Davydov

unread,
Dec 23, 2017, 7:17:01 AM12/23/17
to ISO C++ Standard - Future Proposals
Is there any progress being made on this? As I see now the Microsoft and libc++ implementation maintain trivial copyability, but libstdc++ doesn't: https://godbolt.org/g/tL29Hd

четверг, 22 сентября 2016 г., 22:06:04 UTC+3 пользователь Nicol Bolas написал:

Ville Voutilainen

unread,
Dec 23, 2017, 7:47:05 AM12/23/17
to ISO C++ Standard - Future Proposals
On 23 December 2017 at 14:17, Andrey Davydov <andrey.a...@gmail.com> wrote:
> Is there any progress being made on this? As I see now the Microsoft and
> libc++ implementation maintain trivial copyability, but libstdc++ doesn't:
> https://godbolt.org/g/tL29Hd

The proposal for that hasn't apparently been adopted yet, so this
hasn't popped up as a high-priority
item on the libstdc++ todo list. I suppose I should implement it
anyway, but I can't make any promises
that it'll make it into gcc 8.

Arthur O'Dwyer

unread,
Dec 24, 2017, 8:40:14 PM12/24/17
to ISO C++ Standard - Future Proposals
Coincidentally, "trivial copyability of std::optional" just popped up over on the SG14 list as well:

The fundamental problem (IMO) is that if you make optional<T> trivially copyable, then you have

    optional<int> a = 42;  // correctly constructs an `int` and begins its lifetime
    optional<int> b = a;  // trivially copies some bits into the memory address of `b`

In the `b` case, there is no `int` object actually constructed (assuming the common implementation of `optional<T>` as containing a union of a dummy char and a `T` object, where the `T` object is not constructed by default). So the first access to `b.value()` invokes undefined behavior, as far as I'm aware.

I believe that this problem (A) does not cause incorrect codegen in practice because compilers don't optimize on lifetime information yet; and (B) is actively being tackled by papers such as Ville & Richard's P0593r1 so that such optimizations might be implementable in the future.

If P0593r1 is adopted in its current form, then optional<T> will be able to be trivially_copyable whenever T is trivially_copyable; however, there will be cases where the trivialness of the copy constructor cannot be propagated because of a non-trivial destructor, or vice versa.

–Arthur

Nicol Bolas

unread,
Dec 24, 2017, 11:15:39 PM12/24/17
to ISO C++ Standard - Future Proposals


On Sunday, December 24, 2017 at 8:40:14 PM UTC-5, Arthur O'Dwyer wrote:
On Saturday, December 23, 2017 at 4:47:05 AM UTC-8, Ville Voutilainen wrote:
On 23 December 2017 at 14:17, Andrey Davydov <andrey.a...@gmail.com> wrote:
> Is there any progress being made on this? As I see now the Microsoft and
> libc++ implementation maintain trivial copyability, but libstdc++ doesn't:
> https://godbolt.org/g/tL29Hd

The proposal for that hasn't apparently been adopted yet, so this
hasn't popped up as a high-priority
item on the libstdc++ todo list. I suppose I should implement it
anyway, but I can't make any promises
that it'll make it into gcc 8.

Coincidentally, "trivial copyability of std::optional" just popped up over on the SG14 list as well:

The fundamental problem (IMO) is that if you make optional<T> trivially copyable, then you have

    optional<int> a = 42;  // correctly constructs an `int` and begins its lifetime
    optional<int> b = a;  // trivially copies some bits into the memory address of `b`

In the `b` case, there is no `int` object actually constructed (assuming the common implementation of `optional<T>` as containing a union of a dummy char and a `T` object, where the `T` object is not constructed by default). So the first access to `b.value()` invokes undefined behavior, as far as I'm aware.

That would basically mean that any trivially copyable `union` type cannot be copied at all. I don't buy that the standard says that. Indeed, it very much does not [basic.types]/3:

> For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (4.4) making up obj1 are copied into obj2 , 44 obj2 shall subsequently hold the same value as obj1.

And that's just for doing a memcpy-based copy assignment.

For a `union`, to "hold the same value" as another instance of that union also means to have active the same member subobject as the other `union`. Do you have some specific statement in the standard that says otherwise?

Ville Voutilainen

unread,
Dec 25, 2017, 5:01:01 PM12/25/17
to ISO C++ Standard - Future Proposals
On 23 December 2017 at 14:47, Ville Voutilainen
..but there's a good chance that it might:
https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01524.html

Andrey Davydov

unread,
Dec 26, 2017, 6:00:42 AM12/26/17
to ISO C++ Standard - Future Proposals
вторник, 26 декабря 2017 г., 1:01:01 UTC+3 пользователь Ville Voutilainen написал:
Many thanks to The Elf for the quick patch!

The proposal for that hasn't apparently been adopted yet...
I haven't managed to find any proposal or library issue about this. Could you point out to it or should I create proposal/library issue?
 

Ville Voutilainen

unread,
Dec 26, 2017, 7:28:23 AM12/26/17
to ISO C++ Standard - Future Proposals
On 26 December 2017 at 13:00, Andrey Davydov <andrey.a...@gmail.com> wrote:
>> The proposal for that hasn't apparently been adopted yet...
>
> I haven't managed to find any proposal or library issue about this. Could
> you point out to it or should I create proposal/library issue?

Here: http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0602r1.html

Andrey Davydov

unread,
Dec 26, 2017, 7:32:40 AM12/26/17
to ISO C++ Standard - Future Proposals
вторник, 26 декабря 2017 г., 15:28:23 UTC+3 пользователь Ville Voutilainen написал:
Thanks again!
Reply all
Reply to author
Forward
0 new messages