According to the C++23 standard, what is the output of this program?
#include <iostream>
char a[2] = "0";
struct a_string {
a_string() { *a='1'; }
~a_string() { *a='0'; }
const char* c_str() const { return a; }
};
void print(const char* s) { std::cout << s; }
a_string make_string() { return a_string{}; }
int main() {
a_string s1 = make_string();
print(s1.c_str());
const char* s2 = make_string().c_str();
print(s2);
print(make_string().c_str());
}Temporary objects are destroyed as the last step in evaluating the full-expression that contains the point where they were created.
101
This demonstrates the lifetime of temporary objects, and a potential pitfall, especially when refactoring.
Let's look at main() one line at a time:
a_string s1 = make_string(); creates an a_string, and a is set to 1. This object is not destroyed (and a set back to 0 again) until at the very end of main(), after we're done printing.
Then print(s1.c_str()); is called, printing the value of a, which is now 1.
Next, we do const char* s2 = make_string().c_str();. The temporary a_string created by the call to make_string sets a to 1, but then back to 0 again when it is destroyed. By the time we get to print(s2);, it prints 0. Had this been a real std::string, print(s2); would cause undefined behavior since s2 is an invalid pointer!
In print(make_string().c_str()); the temporary object is instead destroyed after the call to print returns, so 1 is printed.
Temporary objects are destroyed as the last step in evaluating the full-expression (§[intro.execution]) that (lexically) contains the point where they were created.