通过栈中的`std::move`返回变量不安全吗? (编译器对此显示警告)

问题描述 投票:0回答:1

我读了很多答案,局部变量可以通过

std::move
安全地返回。 但是当我尝试时,编译器显示如下警告。

class MyClass {};

MyClass&& func() {
    MyClass c;
    return std::move(c);
}

int main() {
    func();
}


warning: reference to stack memory associated with local variable 'c' returned [-Wreturn-stack-address]
    return std::move(c);
                     ^                      

上面的代码有什么问题?

c++ move rvalue-reference
1个回答
0
投票

在您的代码示例中,您返回对局部变量的(右值)引用。由于函数调用完成后局部变量就被销毁了,使用这样的返回值是未定义的行为


另一方面,如果您按值返回(您应该这么做),那么使用

std::move
可能不是一个好主意。

事实上,由于 NRVO(命名返回值优化),编译器可以执行复制省略以避免不必要的复制/移动。

实际上,NRVO 不是强制性的,因此移动构造函数可能会被调用(但实际上,这不会发生,因为大多数编译器都会执行优化)。 知道,如果你明确使用

std::move

,由于移动构造函数可能有副作用,你使你的变量不符合NRVO的条件,这就将上面的

“移动构造函数
可能被称为”翻译成“移动构造函数将会被称为“这是一种悲观主义 因此,除非您确实想调用移动构造函数(例如,对于内部实现的特定行为),否则您不应该返回

std::move

如果这只是性能问题,编译器会通过复制省略做得比你更好。

因此,正确的版本是:

MyClass func() // Return by value { MyClass c; /* Do whatever you want with c. */ return c; // NRVO (copy elision) }

© www.soinside.com 2019 - 2024. All rights reserved.