简体   繁体   English

C++ 临时变量生命周期?

[英]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 isf2中创建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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM