views:

144

answers:

4

Is a temporary created as part of an argument to a function call guaranteed to stay around until the called function ends, even if the temporary isn't passed directly to the function?

There's virtually no chance that was coherent, so here's an example:

class A {
public:
    A(int x) : x(x) {printf("Constructed A(%d)\n", x);}
    ~A() {printf("Destroyed A\n");}

    int x;
    int* y() {return &x;}
};

void foo(int* bar) {
    printf("foo(): %d\n", *bar);
}

int main(int argc, char** argv) {
    foo(A(4).y());
}

If A(4) were passed directly to foo it would definitely not be destroyed until after the foo call ended, but instead I'm calling a method on the temporary and losing any reference to it. I would instinctively think the temporary A would be destroyed before foo even starts, but testing with GCC 4.3.4 shows it isn't; the output is:

Constructed A(4)
foo(): 4
Destroyed A

The question is, is GCC's behavior guaranteed by the spec? Or is a compiler allowed to destroy the temporary A before the call to foo, invaliding the pointer to its member I'm using?

+9  A: 

Temporary objects exist up until the end of the full expression in which they are created.

In your example, the A object created by A(4) will exist at least until the expression ends just after the return from the call to foo().

This behavior is guaranteed by the language standard:

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception (C++03 §12.2/3).

The lifetime of the temporary may be extended by binding a reference to it (in which case its lifetime is extended until the end of the lifetime of the reference), or by using it as an initializer in a constructor's initializer list (in which case its lifetime is extended until the object being constructed is fully constructed).

James McNellis
Just a note: And their lifetime can be extended by binding the result to a reference.
Stephen
by binding it to a const reference
Greg Domjan
@Greg: Or an rvalue reference.
FredOverflow
@Stephen, @Greg, @Fred: That doesn't really apply to the OP's question, but I've changed the answer anyway to say that the object will last _at least_ until the expression ends and noted the two scenarios under which the lifetime of a temporary may be extended (per C++03 at least; I'm not familiar enough yet with the C++0x rules to bring those up)
James McNellis
Awesome. Thanks to you and Jerry for finding the reference in the spec, I had trouble finding it
Michael Mrozek
+2  A: 

The temporary lasts until the end of the expression it is part of - which in this case is a function call.

anon
A: 

The lifetime of your temp object A(4) will last long enough to call y()

The memory pointed to in the return of y() is not reliable, depending on threading and allocations it may be reallocated and the value changed before the call to foo() makes use of it.

Greg Domjan
Hmmm, apparently MSVC is giving me a non standard response, good to learn the standard.
Greg Domjan
+3  A: 

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

IOW, you're safe -- the A object must not be destroyed until after foo returns.

Jerry Coffin