作为函数调用的一部分创建的临时变量何时被销毁?
作为函数调用参数的一部分创建的临时变量是否保证保留到被调用函数结束,即使临时变量没有直接传递给函数?
实际上不可能是连贯的,所以这里有一个例子:
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());
}
如果 A(4)
直接传递给 foo
它肯定不会被销毁,直到 foo 之后
调用结束,但我正在临时调用一个方法并丢失对它的任何引用。我本能地认为临时 A
会在 foo
启动之前被销毁,但使用 GCC 4.3.4 进行的测试表明事实并非如此;输出是:
构造A(4)
foo(): 4
摧毁A
问题是,规范是否保证 GCC 的行为?或者编译器是否允许在调用 foo
之前销毁临时 A
,从而使指向我正在使用的其成员的指针无效?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
临时对象一直存在到创建它们的完整表达式结束为止。
在您的示例中,由
A(4)
创建的A
对象将至少存在,直到表达式在调用返回后立即结束foo()
。这种行为由语言标准保证:
临时变量的生命周期可以通过绑定对它的引用来延长(在这种情况下,它的生命周期会延长直到引用的生命周期结束),或者将其用作构造函数的初始值设定项列表中的初始值设定项(在这种情况下,它的生命周期会延长,直到正在构造的对象完全构造完毕)。
Temporary objects exist up until the end of the full expression in which they are created.
In your example, the
A
object created byA(4)
will exist at least until the expression ends just after the return from the call tofoo()
.This behavior is guaranteed by the language standard:
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).
§12.2/3:“临时对象在评估完整表达式(1.9)(从词法上)包含它们创建点的最后一步被销毁。”
IOW,你很安全——在
foo
返回之前,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 afterfoo
returns.临时变量持续到它所属的表达式结束——在本例中是函数调用。
The temporary lasts until the end of the expression it is part of - which in this case is a function call.
临时对象
A(4)
的生命周期将持续足够长的时间来调用y()
y()
返回中指向的内存> 并不可靠,根据线程和分配,它可能会被重新分配,并且在调用foo()
使用它之前它的值可能会发生变化。The lifetime of your temp object
A(4)
will last long enough to cally()
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 tofoo()
makes use of it.