0

I'm trying to display a simple message within my first MFC application.

Strangely, the first sample doesn't work, instead the second one works correctly.

auto text = std::to_wstring(1).c_str();
MessageBox(text, NULL, 0); // Not ok, the message is empty

auto temp = std::to_wstring(1);
MessageBox(temp.c_str(), NULL, 0); // Ok, display 1

Can you explain why of this behavior?

bit
  • 934
  • 1
  • 11
  • 32
  • Possible duplicate of [std::string::c\_str() and temporaries](http://stackoverflow.com/questions/10006891/stdstringc-str-and-temporaries) – IInspectable Jan 09 '17 at 18:42

1 Answers1

4

Yes, in the first example, the wstring created by the call to std::to_wstring only has the scope of the line. After the line executes, it is out of scope and its value is dubious.

In the second example, the wstring is still in scope and valid and so the call to .c_str() works.

No, the other answer is wrong. Look at the implementation of c_str(). c_str() returns basically a LPCWSTR... call it a const WCHAR* or const wchar_t* or whatever. However, the return of c_str() is to an internal pointer of wstring. The problem is that after the line of code executes, the wstring returned from to_wstring() is not valid and so the the pointer returned by c_str() is garbage. For fun, try the following code:

//cstr_.cpp
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv)
{
   auto temp = to_wstring(1).c_str();
   wprintf(L"%s\n", temp);

   auto temp2 = to_wstring(1);
   wprintf(L"%s\n", temp2.c_str());

   wstring ws = to_wstring(1);
   auto temp3 = ws.c_str();
   wprintf(L"%s\n", temp3);
}

I compiled the above from a VC++ shell prompt with: cl.exe cstr.cpp

If the other answer is correct, then the last line should have garbage or nothing output because according to the other answer, c_str() is a temp. But, if my answer is correct, then it should output 1 (which it does). If all else fails, look at the implementation source code.

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29
  • Ask him how to reference the temporary wstring created by to_wstring() if it is still in scope. – Joseph Willcoxson Jan 09 '17 at 17:55
  • 1
    @bit: [Temporary object lifetime](http://en.cppreference.com/w/cpp/language/lifetime#Temporary_object_lifetime). – IInspectable Jan 09 '17 at 18:39
  • @IInspectable: thank you very much. Now it's ok. You are right. Thank you again. – bit Jan 09 '17 at 18:44
  • 1
    I take that back. `to_wstring` **does** return a temporary, that's still valid, when calling `c_str()` on it. The return value of the latter gets invalidated, when calling a non-const member function on the string, or it gets destroyed. It is the temporary in the middle, that's responsible for the observed behavior. – IInspectable Jan 09 '17 at 20:02
  • I'm a bit confused. If I assign the result of to_wstring into a variable and then I call c_str in order to assign its result to another one variable, then, I ever will not able ti use value returned from c_str. Why? The Object string is not out of scope! I cannot understand – bit Jan 10 '17 at 04:14