Search code examples
c++memoryreferencelifetimeobject-lifetime

What is the lifetime of an object immediately passed as a parameter?


I had some code that looked something like the following:

struct fooclass {
    char data[32];
}

fooclass makefoo() {
    fooclass res;
    // for example:
    memset(res.data, 0, sizeof(res.data));
    res.data[0] = 43;
    return res;
}

struct do_stuff {
    const fooclass& obj;
    do_stuff(const fooclass& obj_in) : obj(obj_in) { }

    void operate() { /* do things with obj; */ }
}

bool put_it_to_work(struct do_stuff& f) {
    f.operate();
    f.operate();
    return true;
}

bool call_it_all() {
    do_stuff local(makefoo());
    return put_it_to_work(local);
}

With gcc, the code worked fine. With MSVC2012, local.obj became corrupted.

The question is: how long does the fooclass returned by makefoo last? Should it be until the end of call_it_all, or is it just until the end of the do_stuff local(makefoo()) line and I just got lucky? I'd appreciate a reference to the standard.


Solution

  • Here's your problem:

    struct do_stuff {
        const fooclass& obj;
    

    obj is a reference, not a proper object, so no copy is ever made of the result of makefoo(). The real object that obj references is destructed when the local object has finished being constructed, specifically when the anonymous temporary variable that makefoo() returns is destroyed.

    I think you were just lucky that it worked under gcc. Perhaps the object that obj refered to was being destroyed as it should be, only its data was left in RAM and the program appeared to work properly. Perhaps MSVC was "erased" the RAM that obj referred to such that attempts to use it would fail quickly.