什么时候创建作为函数调用的一部分被销毁?

Mic*_*zek 22 c++ memory-management specifications

是一个临时创建的函数调用参数的一部分,保证在调用函数结束前保持不变,即使临时函数没有直接传递给函数?

几乎没有机会是连贯的,所以这是一个例子:

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());
}
Run Code Online (Sandbox Code Playgroud)

如果A(4)直接传递给foo它肯定不会在foo调用结束后销毁,而是我在临时调用一个方法并丢失对它的任何引用.我会本能地认为临时A会在foo开始之前被销毁,但是用GCC 4.3.4测试表明它不是; 输出是:

构造A(4)
foo():4
毁灭A

问题是,GCC的行为是否符合规范?或者是一个编译器允许A在调用之前销毁临时文件foo,使指向我正在使用的成员的指针无效?

Jam*_*lis 20

临时对象一直存在,直到创建它们的完整表达式结束.

在您的示例中,A创建的对象A(4)至少存在,直到表达式从调用返回后结束foo().

语言标准保证了这种行为:

临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点.即使该评估以抛出异常结束也是如此(C++03§12.2/ 3).

临时的生命周期可以通过绑定对它的引用来扩展(在这种情况下,它的生命周期延长到引用的生命周期结束),或者通过在构造函数的初始化列表中使用它作为初始化器(在这种情况下,寿命延长,直到构造的对象完全构造).


Jer*_*fin 6

§12.2/ 3:"作为评估全表达式(1.9)的最后一步,(词法上)包含创建它们的点,临时对象被销毁."

IOW,你是安全的 - Afoo返回之前不得销毁对象.