You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
string_span static array constexpr constructor not actually constexpr #539
When trying to make a constexpr string_span from a static array, like so:
constexpr gsl::string_span<> str {"asdf"};
VS 2017 gives the errors:
error C2131: expression did not evaluate to a constant
note: failure was caused by call of undefined function or one not declared 'constexpr'
note: see usage of 'gsl::basic_string_span<const char,-1>::remove_z'
note: while evaluating 'gsl::basic_string_span<const char,-1>::basic_string_span(&span, &{97,115,100,102,0})'
error C2131: expression did not evaluate to a constant
note: failure was caused by call of undefined function or one not declared 'constexpr'
note: see usage of 'gsl::basic_string_span<const char,-1>::remove_z'
The constructor called here says:
// From static arrays - if 0-terminated, remove 0 from the view
// All other containers allow 0s within the length, so we do not remove them
template <std::size_t N>
constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(arr))
{
}
Since all we really want to do is remove the trailing zero from string literals, it seems like a simpler constructor like so might do what we want and allow for constexpr string spans:
// From static arrays - if 0-terminated, remove 0 from the view
// All other containers allow 0s within the length, so we do not remove them
template <std::size_t N>
constexpr basic_string_span(element_type (&arr)[N]) : span_(arr, arr[N - 1] ? N : N - 1)
{
}
remove_z could also be fixed to be correctly constexpr, I suppose.
The comment seems to imply that we don't care about embedded nulls, so we don't need to look for the first null on the string, just remove the last one if there is one (string literals always have one). If someone hard-coded a static char array with nulls in it, they'd just have to be aware that a single ending null would be removed, but that's no worse than the current situation.
The idea is that remove_z() actually looks for a null-terminator, rather than just assuming the existence of one. I think the preferred path to resolving the issue would be to ensure that remove_z() is constexpr.
Activity
neilmacintosh commentedon Apr 19, 2018
The idea is that
remove_z()actually looks for a null-terminator, rather than just assuming the existence of one. I think the preferred path to resolving the issue would be to ensure thatremove_z()isconstexpr.JordanMaples commentedon Oct 28, 2020
Maintainer's call: Sorry for the delayed reply. gsl::string_span has been removed from the C++ Core Guidelines with isocpp/CppCoreGuidelines#1680.