c++c++11movervo

Class containing string: what really happens when it's returned from a function?


Not that I don't trust my compiler, but I like to know what's going on. Let's say I have

struct Foo {
  std::string s;
};

and I want to create one of those (on the stack), fill in the very long string, and return it from my function.

Foo f() {
  Foo foo {my_very_long_string};
  return foo;
  // OR: return Foo {my_very_long_string};
}

I know there's such things as RVO and move semantics; how do I know that they're being used, and at runtime it's not allocating a new string with data on the heap, copying it, and freeing the old one? (Other than my program will get slow.)

Is it using a move constructor to reuse the string data? Or is it using RVO to actually return the same string?


Solution

  • NRVO or move for named objects

    In the function:

    Foo f() {
      Foo foo{my_very_long_string};
      return foo;
    }
    

    The object foo has a name (i.e.: foo), it is a named object.

    Named RVO (NRVO), which is an optional optimization, may occur. If no NRVO takes place, then foo is moved, since it is a local object and therefore treated as an rvalue in this context (i.e.: the return statement).


    RVO/copy elsion or move for unnamed objects

    However, in the function:

    Foo f() {
      return Foo{my_very_long_string};
    }
    

    A unnamed object, which is the one resulting from Foo{my_very_long_string}, is concerned.


    No heap allocation for a new string will happen in any of the cases above.