It seems to me that `optional` is not usable in compile-time before C++20, because switching union active member is not allowed, and so it doesn't make sense to mark `optional()` as constexpr, but maybe I have missed something.
That's a good point. Interestingly enough, the following code happened to work on both gcc and clang with C++17:
  constexpr void foo() {
    std::optional<int> opt;
    opt = 2;
  }
yet it's clear that there is an "invocation of an assignment operator that would change the active member of a union" (removed in p1330) in both libstdc++ and libc++.

why in your initial example `dummy` is an array? If it's a single object, pessimization due to zero-initialization will be reduced 
This code was minimized from the abseil's optional (https://github.com/abseil/abseil-cpp/blob/master/absl/types/internal/optional.h#L79). The comment there says that the reason is to avoid a gcc-warning.
Another reason (a bit technical and implementation specific) was that having union members of different sizes were optimized by clang/llvm by storing shared and non-shared parts of the union in separate memory locations, which caused conservative garbage collection used in the Chrome's renderer to miss the pointer stored in an optional.

If it's a single object, pessimization due to zero-initialization will be reduced
Having zero-initialization even for a single empty object is already pessimization. We're just lucky that for a single object it gets optimized away by clang, but at the same time are unlucky that for the whole array it doesn't (as opposed to gcc).

It would be very strange if for the `pair<int, array<int, 1>> p;` p.first == 0, but p.second[0] has indeterminate value.
The example totally makes sense, thanks.

I think that technically even for a single empty object its 'value' may be observable (e.g. through char* aliasing), but I don't think there is a real use case for this, given that compilers already optimize such cases. I wonder if it would make sense to expand the definition of empty class from type traits to the Core to allow for more optimizations.


вс, 2 февр. 2020 г. в 11:11, Andrey Davydov <andrey.davydov@jetbrains.com>:
On Sat, Feb 1, 2020 at 4:46 PM Anton Bikineev <ant.bikineev@gmail.com> wrote:
Or, even better, remove definition of `optional()` to make it trivially-default-constructible?
Removing the definition of optional() (or in general having it not user-provided) makes it deleted for T that have non-trivial default constructor (since T is in union).

but I still don't see a reason to value-initialize `dummy`.
Value-initialization appears to be needed for the constructor to be constexpr.
It seems to me that `optional` is not usable in compile-time before C++20, because switching union active member is not allowed, and so it doesn't make sense to mark `optional()` as constexpr, but maybe I have missed something.
A slightly offtopic question: why in your initial example `dummy` is an array? If it's a single object, pessimization due to zero-initialization will be reduced (https://godbolt.org/z/PxDR8J).

--
Andrey Davydov


--
Sincerely,
Anton.