Consider the following C++ code:
#include <iostream>
#include <string>
#include <string_view>
void echo(std::string & input)
{
std::string_view input_v = input;
std::cout << input_v << std::endl;
input.clear();
}
int main()
{
std::string str1{"This is a string"};
echo(str1);
}
Function echo
creates an instance of std::string_view
, uses it and then calls input.clear()
, which clears the content of the buffer of the string input
, where the input_v
is pointing to.
std::string_view input_v
is not accessed after the call to input.clear()
, but I assume that immediately after the call to input.clear()
the control flow is still within the scope of the function body, therefore, all local objects created therein still exist, therefore, the input_v
continues to point to the content of the string input
, even if just "for a little while".
The cppreference.com mentions in the section "Notes":
It is the programmer's responsibility to ensure that
std::string_view
does not outlive the pointed-to character array
Taking this into consideration, does the above code violate this rule?
The example in the notes implicitly assume you want to use the string view:
std::string_view bad{"a temporary string"s};
// v "Bad" case: use the string view
std::cout << bad; // UNDEFINED !!
It's the "Bad" case because trying to read the string from bad
results in undefined behavior. Though, as long as you do not use the string view there is no problem:
{
std::string_view bad{"a temporary string"s};
// ^ useless but no problem
}
In particular, a string_view
s destructor is not doing anything with the referenced string.
This is similar to invalid pointers (or iterators) that only cause trouble when dereferenced:
{
Foo* p;
{
Foo f;
p = &f;
}
// here p is a dangling pointer
// no problem as long as it is not dereferenced
// it can be assigned a different value eg p = nullptr;
// or just let go out of scope
}
To conclude ...
Taking this into consideration, does the above code violate this rule?
Yes, your code violates the rule. However, the rule is a little too strict. The string_view
can outlive the string, it's just no valid view once the string is gone. The code using the string view typically is not aware of the lifetime of the string. By making sure the string outlives the string view, you are on the safe side, because it prevents reading from the view after the lifetime of the string ended.
Is your code safe?
Yes. The rule is sufficient but not necessary to ensure you do not attempt to read the string via the string view after the string ceases to exist.