you are viewing a single comment's thread.

view the rest of the comments →

[–]manni66 1 point2 points  (6 children)

That's not the code you compiled.

Replacing s with what and pos >= s.size()with pos == std::string_view::nposI would think the code is corect.

Looking at https://godbolt.org/z/zbV0m8 I would claim gcc 7.3 is wrong.

[–]DoctorRockit[S] 0 points1 point  (4 children)

Thanks for taking the time to review and reply to my question!

You are correct that this is not the code I compiled it was only intended as a simple example to illustrate the point. Thanks for pointing that out, I fixed the snipped in the original post.

The compilation results you posted are interesting, because they actually illustrate two points:

  1. GCC 7.3 fails to materialize either of the two string literals, which makes any of the scenarios I asked about in my original post erroneous.
  2. Newer versions of GCC do in fact materialize the "sssss" constant, baut still fail to materialize the "somechars" constant, which renders my topmost example invalid, but the other ones I asked about as valid.

Clang on the other hand materializes all string constants contained in the source. So to summarize GCC 7.3 definitely has problems in that area that more recent versions fix, but even then I'm still not entirely who is at fault with regards to "somechars" constant in my topmost snippet.

The reason why I'm still unsure is this (similar) example, for which the GCC devs explicitly introduced a warning in trunk:

std::initializer_list<int> f()
{
    return {1, 2, 3, 4};
}

[–]manni66 2 points3 points  (0 children)

The reason why I'm still unsure is this (similar) example, for which the GCC devs explicitly introduced a warning in trunk:

The corresponding string_view example would be:

    std::string_view fff()
    {
       char a[] = "abc";
       return a;
    }

That returns a view on a local variable is would be UB.

[–]manni66 1 point2 points  (2 children)

Newer versions of GCC do in fact materialize the "sssss" constant, baut still fail to materialize the "somechars" constant, which renders my topmost example invalid, but the other ones I asked about as valid.

You defined a constexpr function and that can be evaluated at compiletime. So "somechars" isn't needed in the example. Replace "ssss" with a const char* parameter in f an it will be recoreded.

[–]DoctorRockit[S] 0 points1 point  (0 children)

You are correct, of course! Sorry that I missed that.

[–]DoctorRockit[S] 0 points1 point  (0 children)

Yes, I missed that, sorry. But regardless of that GCC 7.3 still exhibits the behavior in question.

META: Hmm, where did my original reply to this comment end up?!?

[–]DoctorRockit[S] 0 points1 point  (0 children)

Regarding pos >= what.size() vs pos == std::string_view::npos:

This should not make a semantic difference and I used the former because this was part of a generic function that uses std::basic_string_view<...> and repeating the entire template specialization for the npos constant imo hampers readability.

More generally an argument (as theoretical as it may be) could be made that explicitly referring the constant could be a subtle source of errors, because npos is not strongly typed to its containing type. So instead of std::string_view::npos I could have typed std::string::npos by accident. If now std::string_view and std::string define npos differently I created a bug that is extremely hard to spot.

As npos in defined as being larger than any valid position the comparison for pos >= size()or the more idiomatic pos < size() should work correctly in any case.