The standard doesn't say anything about the implementation of those two constructors. According to [optional.ctor]:
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
- Ensures:
*thisdoes not contain a value. - Remarks: No contained value is initialized. For every object type
Tthese constructors shall beconstexprconstructors (9.1.5).
It just specifies the signature of those two constructors and their "Ensures" (aka effects): after any of those constructions the optional doesn't contain any value. No other guarantees are given.
Whether the first constructor is user-defined is implementation-defined (i.e depends on the compiler).
If the first constructor is user-defined, it can of course be implemented as setting the contains flag. But a non-user-defined constructor is also compliant with the standard (as implemented by gcc), because this also zero-initialize the flag to false. Although it does result in costy zero-initialization, it doesn't violate the "Ensures" in specified by the standard.
As it comes to real-life usage, well, it is nice that you have dug into the implementations so as to write optimal code.
Just as a side-note, probably the standard should specify the complexity of those two constructors (i.e O(1) or O(sizeof(T)))