mardi 6 juin 2017

c++ - NRVO and move

I have read a few posts about move functions (http://ift.tt/R70kpN for example), and I wanted to observe move operators in action. So I tried the following code:

#include <vector>
#include <cassert>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;

vector<double> operator+(const vector<double>& a, const vector<double>& b){
  assert(a.size()==b.size());
  vector<double> result(a.size(),0);
    transform (a.begin(), a.end(), b.begin(), result.begin(), std::plus<double>());
  cout<<&result<<endl;
  return result;
}

int main(int argc, char const *argv[]) {
  vector<double> a,b;
  for (int i=0;i<10;i++){
    a.push_back(i);
    b.push_back(1);
  }
  std::vector<double> c=a+b;
  cout<<&c<<endl;
  return 0;
}

I was expecting to obtain the same address for the local variable result and c since move operators are implemented for vector. And I obtained exactly that, but with and without the flag -std=c++11. That is when I learned about NRVO (c++11 Return value optimization or move?), so I disabled it with the flag -fno-elide-constructors and now the address is different, even with the flag -std=c++11. Is there an issue with my code or did I understand something wrong about move operators ?

From what I understood, returning by value should be enough for the move operator to kick in (C++11 rvalues and move semantics confusion (return statement)).

PS: I tried with GCC 6.3.0_1 and Apple LLVM version 8.1.0 .

Aucun commentaire:

Enregistrer un commentaire