此代码是否导致UB

Does this code causes UB?

本文关键字:UB 是否 代码      更新时间:2023-10-16

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

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(的指针。

bar(a.foo().c_str());
bar(a.foo().substr().c_str());

简短回答-是的,两者都很安全。

你看到的是一个右值

右值(历史上称为右值,因为右值可能出现在赋值表达式的右侧(是xvalue、临时对象或其子对象,或与对象无关的值。

阅读更多:什么是rvalues、lvalues、xvalues、glvalues和prvalues?