Lifetime of return value in comma separated statements

346 Views Asked by At

Is the order of execution of the three commented lines below guaranteed?

struct S
{
    S() { /* called 1st */ }
    ~S() { /* called 3rd */ }
};

boost::shared_ptr<S> f() 
{
    return boost::shared_ptr<S>(new S); 
}

int second() { return 0; /* called 2nd */ }

int test()
{
    return (f(), second());
}

With my compiler, the shared_ptr returned by f() seems to persist until after second() is called. But is this guaranteed by the standard and thus other compilers?

1

There are 1 best solutions below

0
On BEST ANSWER

Yes.

Temporaries persist until the completion of the full-expression.

[n3290: 12.2/3]: When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). 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. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.

And:

[n3290: 1.9/10]: A full-expression is an expression that is not a subexpression of another expression. If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition. A call to a destructor generated at the end of the lifetime of an object other than a temporary object is an implicit full-expression. Conversions applied to the result of an expression in order to satisfy the requirements of the language construct in which the expression appears are also considered to be part of the full-expression. [..]

This means that both f() and second() should exist until execution returns from test() with the result of evaluating the latter.