0

I use function:

std::vector<int>&& f() {
    std::vector<int> s;
    for (auto i : names) {
        s.push_back(this->f2(i));
    }
    return std::move(s);
}

the main function is:

int main() {
    auto g = f();
}

I use debugger monitor and find that before executing return std::move(s), s is not empty, but why g is empty then?

Sprout
  • 11
  • 1
  • 1
    You're returning a dangling reference, so the behaviour is undefined. – molbdnilo Apr 17 '23 at 14:38
  • why would it be different before the vector is returned? You have something in `s` and nothing in `g` and *then* return it – 463035818_is_not_an_ai Apr 17 '23 at 14:38
  • 1
    `std::vector&& f()` -- Why did you choose to return an r-value reference? It isn't something that turns up in most user-written C++ code, so you must have had a reason to do this. – PaulMcKenzie Apr 17 '23 at 14:40
  • Dangling reference aside, it also matters when, where and how you check the contents. You must always step *over* the initialization or assignment, or it won't have happened yet. – Some programmer dude Apr 17 '23 at 14:40
  • Also, from the code you've show, it's very hard to figure out what the `this` pointer refers to. And `names`. – Adrian Mole Apr 17 '23 at 14:41
  • If you remove the rvalue reference and `std::move` call, things get moved out automatically. Furthermore, you can get even better than a move in numerous cases. – chris Apr 17 '23 at 14:42
  • Because this vector was temporarily created in the function. I want to move it to `g` without incurring any assignment overhead. – Sprout Apr 17 '23 at 14:42
  • @Sprout: just as a simple rule of thumb, *never* use `std::move` on a value you're returning. The compiler can already recognize that a return value is a xvalue (a type of rvalue), but using `std::move` inhibits some other optimizations (RVO/NRVO), so it has no upside, and at least a potential downside. – Jerry Coffin Apr 17 '23 at 14:50

1 Answers1

0

This is due to the fact, that f() returns a rvalue reference to a local object s in f(). This is a dangling reference, as the object referenced will not be existent anymore after f() returns. In main() you then retrieve an rvalue reference to said object, which will result in undefined behaviour.

To fix this you should return a copy of the local variable s like this:

std::vector<int> f() {
    std::vector<int> s;
    for (auto i : names) {
        s.push_back(this->f2(i));
    }
    return s;
}
Cosemuckel
  • 397
  • 1
  • 8
  • Can *you* tell me what the `this` pointer refers to? Can you compile this code? – Adrian Mole Apr 17 '23 at 14:43
  • this will use RVO optimization right? – Sprout Apr 17 '23 at 14:44
  • This is NRVO, and the optimization is permitted but not mandatory. – Raymond Chen Apr 17 '23 at 14:44
  • Note that, as the OP's code *seems* to be a member function of a class, that class *may* have an `s` member and the error *could be* that they've re-declared it inside the function. That would present a different problem with a (potentially) different solution. – Adrian Mole Apr 17 '23 at 14:46
  • @AdrianMole ... except that the usage of `s` within the function refers to the variable defined in the function, even if there is something named `s` in an enclosing scope (such as a member of the class). – Peter Apr 17 '23 at 14:49
  • @Peter Indeed. But I've seen numerous problems posted on SO where the error is caused by a redeclaration of a member variable as a function-local variable. – Adrian Mole Apr 17 '23 at 14:56