这段代码会导致UB吗?

时间:2016-09-27 08:47:48

标签: c++

我检查了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
}

2 个答案:

答案 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::stringc_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?