[英]C++ temporary variable lifetime?
I know this is valid in C++, because temporary from std::string("xxx")
lives to the end of the full expression it appears in.我知道这在 C++ 中是有效的,因为来自
std::string("xxx")
临时性一直存在到它出现的完整表达式的末尾。
printf("%s\n", std::string("xxx").c_str());
And this is valid too:这也有效:
std::string f1() {
return std::string("xxx");
}
void g1() {
printf("%s\n", f1().c_str());
}
But is this valid?但这是有效的吗? if not, why?
如果不是,为什么?
const char* f2() {
return std::string("xxx").c_str();
}
void g2() {
printf("%s\n", f2());
// or: std::string x = f2(); // is this valid?
}
The temporary std::string
inside of f2
is destroyed when the function returns.当函数返回时,
f2
的临时std::string
被销毁。 The char*
will be dangling. char*
将悬空。
EDIT: In response to the comment, std::string x = f2()
is also not valid.编辑:作为对评论的回应,
std::string x = f2()
也无效。 It's still bad to initialize a std::string
from a dangling pointer.从悬空指针初始化
std::string
仍然很糟糕。
The exact same rule applies.完全相同的规则适用。 The full-expression in which the
std::string
was created in f2
is在
f2
中创建std::string
的完整表达式是
std::string("xxx").c_str()
together with the construction of the return value from it.以及从中构造返回值。
After this expression executed and the construction of the return value executed, the temporary std::string("xxx")
will be destroyed.执行此表达式并执行返回值的构造后,临时
std::string("xxx")
将被销毁。 Since destruction of the temporary std::string
makes the const char*
obtained from .c_str()
and copied into the return value invalid, the return value of the function cannot be used in any way.由于临时
std::string
销毁使得从.c_str()
获得并复制到返回值中的const char*
无效,因此不能以任何方式使用该函数的返回值。
For f1
the same applies (details relating to temporary materialization and copy elision, especially in C++17, aside).对于
f1
,同样适用(有关临时物化和复制省略的详细信息,尤其是在 C++17 中,旁白)。 The temporary std::string
is destroyed after construction of the return value.临时
std::string
在构造返回值后被销毁。 But in this case this is not a problem, because the return value is not a pointer to something that was destroyed, but an independent std::string
object itself.但在这种情况下,这不是问题,因为返回值不是指向已销毁对象的指针,而是一个独立的
std::string
对象本身。 This std::string
object will live until the end of the full-expression in which the call to f1
appears, ie until the end of这个
std::string
对象将一直存在到出现对f1
的调用的完整表达式的结尾,即直到
printf("%s\n", f1().c_str())
The following would be fine as well:以下也可以:
std::string f3() {
return std::string("xxx").c_str();
}
Here again, a new std::string
is created in the return value, which will live until the end of the full-expression in which f3
is called.同样,在返回值中创建了一个新的
std::string
,它将一直存在到调用f3
的完整表达式结束。
In practice, for f1
, since std::string("xxx");
实际上,对于
f1
,因为std::string("xxx");
is already a prvalue of type std::string
, copy elision will be applied, so that there is really only one temporary object, the return value of f1
.已经是
std::string
类型的纯右值,将应用复制省略,因此实际上只有一个临时对象,即f1
的返回值。 The intermediate temporary will be eliminated and the return value directly constructed from "xxx"
.中间临时将被消除,返回值直接由
"xxx"
构造。 This is mandatory since C++17 and was allowed and common before C++17.从 C++17 开始这是强制性的,并且在 C++17 之前是允许和常见的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.