逗号分隔语句中返回值的生命周期

3
下面三行被注释的代码执行顺序是否有保障?
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());
}

使用我的编译器,f() 返回的 shared_ptr 似乎会一直持续到调用 second()。但这种行为是否被标准保证并适用于其他编译器呢?


可能是临时变量的生命周期的重复问题。 - fredoverflow
1个回答

8

是的

临时变量会一直存在,直到full-expression完成。

[n3290: 12.2/3]: 当实现引入一个具有非平凡构造函数(12.1、12.8)的类的临时对象时,它必须确保为临时对象调用构造函数。同样,对于具有非平凡析构函数(12.4)的临时对象,必须调用析构函数。临时对象在评估包含创建它们的点的(词法上)full-expression(1.9)的最后一步被销毁。即使该评估以抛出异常结束,这也是真实的。 销毁临时对象的值计算和副作用仅与full-expression相关,而不与任何特定的子表达式相关。

并且:

[n3290: 1.9/10]: 完整表达式是不是另一个表达式的子表达式的表达式。如果语言构造定义为产生对函数的隐式调用,则使用语言构造被认为是表达式,目的是根据此定义。在对象的生命周期结束时生成的析构函数调用是一个隐式的完整表达式,而不是临时对象。为了满足表达式所在的语言构造的要求,应用于表达式结果的转换也被认为是完整表达式的一部分。[..]

这意味着f()second()都应该存在,直到执行从评估后者的结果返回到test()为止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接