banner
cells

cells

为美好的世界献上 code

Q295

Q295#

// using C++17
#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());
}

Explain#

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.

in the standard: "Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created."

Answer#

click to see answer 101
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.