On Windows, I have some fairly straightforward move constructors defined for some matrix classes.
One would expect the move constructor to be called when the object is returned from the example function below - and it is when compiled with Visual C++ 2015 update 3. When compiled with Intel 17u3, the behaviour is bizarre. Neither the move constructor OR the copy constructor are called.Everything is compiled in DEBUG mode,IPO is off. I can understand that perhaps the compiler can be clever when all optimizations are on, but this is with all optimizations off.
Visual C++ 2015 output
constructor 1:FloatSymMat
move constructor:FloatSymMat
destructor:~FloatSymMat
about to call std::move
move constructor:FloatSymMat
destructor:~FloatSymMat
destructor:~FloatSymMat
Intel C++ output
constructor 1:FloatSymMat
about to call std::move
move constructor:FloatSymMat
destructor:~FloatSymMat
destructor:~FloatSymMat
If I EXPLICITLY call
FloatSymMat tmp_mat = std::move(symmat);
Then the move constructor is called as expected.
// testmoveconstructor.cpp : Defines the entry point for the console application. // #include <vector> #include <iostream> using namespace std; inline unsigned SymMatSize(unsigned n) { return n*(n + 1) / 2; } class FloatSymMat { private: std::vector<float> vec; unsigned n; // The data which define the matrix public: FloatSymMat(); FloatSymMat(const FloatSymMat&); FloatSymMat(FloatSymMat&&)noexcept; FloatSymMat(unsigned n, unsigned nAgain); FloatSymMat(unsigned n, unsigned nAgain, float initval); ~FloatSymMat(); }; FloatSymMat::FloatSymMat(unsigned M, unsigned N) : vec(SymMatSize(N), 0) { cout << "constructor 1:"<< __func__ << endl; n = N; } FloatSymMat::FloatSymMat(unsigned M, unsigned N, float initval) : vec(SymMatSize(N), initval) { cout << "constructor 2:"<< __func__ << endl; n = N; } inline FloatSymMat::~FloatSymMat() { cout << "destructor:"<< __func__ << endl; } inline FloatSymMat::FloatSymMat() : vec() { cout << "default constructor:"<< __func__ << endl; n = 0; } inline FloatSymMat::FloatSymMat(const FloatSymMat& A) : vec(A.vec) { cout << "copy constructor:"<< __func__ << endl; n = A.n; } inline FloatSymMat::FloatSymMat(FloatSymMat&& A)noexcept : vec(std::move(A.vec)) { cout << "move constructor:"<< __func__ << endl; n = A.n; A.n = 0; } FloatSymMat testReturn() { FloatSymMat symmat(3, 3); return symmat; } int main() { FloatSymMat tmp = testReturn(); cout << "about to call std::move"<< endl; FloatSymMat tmp_mat = std::move(tmp); return 0; }