microsoft / GSL

Guidelines Support Library
Other
6.14k stars 738 forks source link

gsl::not_null is trivially copyable, but not trivially move-constructible #1050

Closed VoidPhantom closed 1 year ago

VoidPhantom commented 2 years ago

The gsl::not_null class template has:

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.

dmitrykobets-msft commented 2 years ago

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 https://github.com/microsoft/GSL/issues/1051.