gsl::not_null is trivially copyable, but not trivially move-constructible
VoidPhantom opened this issue · comments
The gsl::not_null
class template has:
- a compiler-generated trivial destructor;
- an explicitly defaulted trivial copy constructor;
- an explicitly defaulted trivial copy assignment operator;
- no move constructor;
- no move assignment operator.
This makes it trivially copyable. However, move construction of an object of this class invokes a non-trivial, non-noexcept constructor template (include/gsl/pointers
, line 90). This is unusual and unexpected; in fact, this triggers a bug in libstdc++’s implementation of std::variant
. This could be fixed by adding explicitly defaulted move constructor and move assignment operator.
Hi @VoidPhantom, thanks for investigating this. As far as I can tell, the reason why the not_null type doesn't have a defaulted move constructor and instead relies on a templated alternative (which is not noexcept & has a non-trivial implementation) is that it performs a nullcheck upon construction from a moved-from not_null instance. This problem should be resolved in tandem with a larger design change for gsl::not_null
, for which I've created issue #1051.