我检查了gcc和clang,两者都没有生成任何警告。我想foo()的临时生命周期会延长,直到完全表达式结束,这是bar函数调用中的分号所在。
#include <iostream>
#include <string>
struct A
{
std::string foo() const{ return "aaa"; }
};
void bar(const char* c) {
std::cout << c;
}
int main()
{
A a;
bar(a.foo().c_str()); // Is this safe?
bar(a.foo().substr().c_str()); // or this
}
答案 0 :(得分:7)
foo()
(和substr()
)返回的临时值将继续存在,直到bar
调用结束(在方法调用链之后),这是安全的。
int main()
{
A a;
bar(a.foo().c_str());
//temporary is destroyed here
bar(a.foo().substr().c_str());
// and here
}
经典的未定义行为案例:
int main()
{
A a;
const char* charPtr = a.foo().c_str();
printf("%s", charPtr);
}
创建临时std::string
,c_str()
返回指向它的缓冲区的指针,临时超出范围并被销毁。 charPtr
现在是指向无效位置的指针(死std::string
)。
答案 1 :(得分:2)
bar(a.foo().c_str());
bar(a.foo().substr().c_str());
简短回答 - 是的,两者都是安全的。
您正在查看的是 rvalue 。
rvalue(所谓的历史,因为rvalues可能出现在赋值表达式的右侧)是xvalue,临时对象或其子对象,或者是与对象无关的值。 / p>
了解详情:What are rvalues, lvalues, xvalues, glvalues, and prvalues?