microsoft / GSL

Guidelines Support Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.