Community
cancel
Showing results for 
Search instead for 
Did you mean: 
AndrewC
New Contributor I
167 Views

Intel Compiler 17.0u3 not calling move constructor

Jump to solution

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;
}

 

 

0 Kudos
1 Solution
Bastian_B_
New Contributor I
167 Views

http://en.cppreference.com/w/cpp/language/copy_elision ?

Keywords to look for are RVO (Return Value Optimization) and NRVO (Named Return Value Optimization).

View solution in original post

4 Replies
AndrewC
New Contributor I
167 Views

One additional comment - I can understand if the compiler is doing something very smart here - as the code seems to function as expected - but I am a bit baffled.

Also, anyone working through  a C++ move constructor tutorial will get really confused!

Bastian_B_
New Contributor I
168 Views

http://en.cppreference.com/w/cpp/language/copy_elision ?

Keywords to look for are RVO (Return Value Optimization) and NRVO (Named Return Value Optimization).

View solution in original post

AndrewC
New Contributor I
167 Views

Very interesting and that explains it.  Is the RVO  controlled by any optimization switch on the compiler or is it always on by default?

Judith_W_Intel
Employee
167 Views

 

Return value optimization is on by default.

Reply