samedi 23 avril 2016

Understanding return value optimization from a factory method and static variable assignment (Visual Studio)

In a library I have a class A that's created and filled in a factory method of a class C. The returned object is then assigned to a static member var in class B. My problem is that return value optimization doesn't seem to kick in, at least in Visual Studio, it works as expected in XCode (with clang). What happens is that the d-tor of class A is called before the defined move assignement operator is used. In the d-tor I free some memory in A and hence after that the data is no longer valid.

class A {
public:
  A();
  A(const &other);
  A(const &&other);

  A& operator = (const &other);
  A& operator = (const &&other);
};

class B {
private:
  static A _a;
  struct Initializer {
    Initializer();
  };
  static Initializer _init;
};

and

B::Initializer::Initializer() {
  C c;
  _a = c.factoryMethod();
}

B::Initializer B::_init;

The factory method is quite simple:

A C::factoryMethod() {
  A a;
  ....
  return a;
}

On return a the copy constructor of A is called, followed by the d-tor. After that the move operator is triggerd (on assignment of the result to _a in B).

That is quite the opposite of what RVO is supposed to do. There should never be a copy (and hence a destruction, except when B is deleted). So, why's that not working as expected?

Aucun commentaire:

Enregistrer un commentaire