I recently found the following code pattern in a C++ code base, and I am now wondering if it is safe according to the C++ standard. (The real code passed the const char* pointer through several function layers, but I condensed it down to its essential form.)
#include <string>
class NetworkSocket
{
public:
void SetPort(const char* port)
{
m_port = port;
}
private:
std::string m_port;
};
int main()
{
const int port = 42;
NetworkSocket socket = {};
socket.SetPort(std::to_string(port).c_str());
}
Specifically, I want to know if the call to SetPort() is safe, or if we are invoking undefined behavior, or accessing (potentially) deleted memory.
I tried to figure it out myself using cppreference, but got stuck in the definitions. I got as far as:
std::to_string()returns a prvalue, thus creating a temporary object.- The call to
c_str()extends the temporary's lifetime. (At least since C++17, before I am not sure.) - From here on I am not sure. It seems that the lifetime of the temporary ends here, making the access to the
const char*pointer undefined behavior. However, when I tried running the code through clang`s undefined behavior sanitizer no problems were found... https://godbolt.org/z/EfcvePoWe
Please quote the relevant standard rules, and explain the differences between the standard versions (if there are any).
This is well-defined.
Here:
The temporary object is the
std::stringobject that's the return value fromstd::to_string. The full-expression is, unremarkably, this entire expression. So the temporary object -- the one that owns itsc_str()-- gets destroyed after the call toSetPort()returns. The End.(there are two exceptions to this rule, they do not apply here).