Assigning a std::string's c_str() result to that same std::string guaranteed safe by the standard?

Viewed 145

Is the following code guaranteed safe by the standard, with regards to std::string?

#include <string>
#include <cstdio>

int main() 
{
    std::string strCool = "My cool string!";
    const char *pszCool = strCool.c_str();
    strCool = pszCool;
    printf( "Result: %s", strCool.c_str() );
}

I've seen statements that indicate the result of c_str is only guaranteed safe to use until another method call on the same std::string is made, but it's not clear to me whether it's safe to pass that const char * back into the assignment method or not.

When tested using real-world compilers (GCC, Clang, and MSVC at their most recent versions) they all seem to support this behavior.

Furthermore, the compilers also support assigning a suffix of the string back to itself, e.g. strCool = pszCool + 3 in this example; the result will be that the string has the same value as what was passed into it.

Is this behavior guaranteed somehow, or am I just lucky that the standard libraries provided by the compilers I've tested support this case?

1 Answers

In C++17, this was specified as:

basic_string& operator=(const charT* s);

Returns: *this = basic_string(s).

Remarks: Uses traits::length().

This sequence of operations guarantees that a copy is made before the original storage is destroyed. While a standard library is not required to implement this call using this exact sequence of operations, it is required to have the same behavior as described.

In C++20, this wording was reworked, but I would be surprised if the meaning was changed.

Related