c++stringassertc-stringsstring-view

Is there a safe way to assert if a string view is null terminated?


I have some part in my code that uses string view extensively. It would be inconceivable to use std::string everywhere, and char const* won't work since there is associative containers, many comparisons and such operations that are hard to do with plain raw strings.

However, there is a place that will eventually deal with a C API, and it needs null terminated strings:

auto sv = std::string_view{/* ... */};
c_api(sv.data());

Although this works fine in my case, I'd like to be sure everything is okay and assert that the strings are null terminated, as my system constructing the string views and send it there will not use substring views, and will either make them from string literals or std::string. I know I will be okay.

The thing however is that another programmer may not know all of this and try to use substr on a string view, or send a non null terminated string. A non null terminated string is bad since it will lead to undefined behaviour, but a substring in the string view is even worse, since the upper limit will not be applied when sent to the C API and no undefined behavior will be invoked, but will instead introduce a really hard to find bug with unintended behavior.

So I wanted to communicate that using an assert:

auto sv = std::string_view{/* ... */};
assert(*(sv.data() + sv.length()) == '\0'); // Yay?
c_api(sv.data());

But I find it incomplete and error prone, since it may read out of bound of a null terminated string.

Is there a way to safely assert that a string view is indeed null terminated?


Solution

  • It might be a pain, but I would write my own string_view that is guaranteed to be null terminated.

    Since a string_view can be constructed like

    char array[3] = {'B', 'a', 'r'};
    std::string_view array_v(array, sizeof array);
    

    testing

    *(sv.data() + sv.length()) == '\0'
    

    is undefined behavior in that case since the last valid index is 2 but you access 3. std::string_view would need to exposes information it can't know in order for you to do this and since it can't, you can't reliably know.