C++11 moves

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

43 Replies - 1039 Views - Last Post: 03 September 2013 - 03:12 PM Rate Topic: -----

#1 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

C++11 moves

Posted 31 August 2013 - 01:37 PM

This topic got me thinking about C++11 moves, so I did some testing and ran into a problem. The code below works as expected, but if I try to add the move constructor it will not compile (Overload resolution selected implicitly-deleted copy assignment operator) unless I remove the vector erase myvector.erase(myvector.begin()+1);. Even though it does run in that case, the output for testing the existence of the objects is wrong:
Testing existence of objects:
A (-1901587283) is here. 0x100103ac0
A (0) is here. 0x100103ac4
A (-1941420756) is here. 0x100103ac8
A (32767) is here. 0x100103acc
A (0) is here. 0x100103ad0
A (0) is here. 0x100103ad4
A (0) is here. 0x100103ad8
A (0) is here. 0x100103adc
A (0) is here. 0x100103ae0


Have I messed up the move constructor? By the way, if I add number = b.number; to the move constructor the results will be fine, but the erase still causes the compile error. That seems to make this a copy and not a move though, so I'm not sure how this whole C++11 thing is working.
#include <iostream>
#include <string>
#include <vector>

class A
{
public:
	int number;
	A(int n)
	{
		number = n;
		std::cout << "A: " << number << " " << this << " created." << std::endl;
	}
	
	/*
	A(A &&B)/>/>
	{
		std::cout << "A:" << this << " moved from " << &b << std::endl;
	}
	//*/
	
	A(const A & aIn)
	{
		std::cout << "A:" << this << " copied from " << &aIn << std::endl;
		number = aIn.number;
	}

	~A()
	{
		std::cout << "~A ("<< number << ") " << this << std::endl;
	}
	
	void Am_I_here()
	{
		std::cout << "A ("<< number << ") is here. " << this << std::endl;
	}
};

int main(int argc, const char * argv[])
{
	std::vector <A> myvector;
	for (int i = 0; i < 9; i++) {
		std::cout <<"push "<< i << std::endl;
		myvector.push_back(A(i));
		myvector[i].Am_I_here();
	}

	std::cout << "Testing existence of objects:"<< std::endl;
	for (long i = 0; i < myvector.size(); i++) {
		myvector[i].Am_I_here();
	}
	std::cout << "erasing"<< std::endl;
	
	myvector.erase(myvector.begin()+1);
	
	std::cout << "Finishing..."<< std::endl;
    return 0;
}


This post has been edited by CTphpnwb: 31 August 2013 - 02:48 PM


Is This A Good Question/Topic? 0
  • +

Replies To: C++11 moves

#2 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 31 August 2013 - 02:08 PM

Hmmm, I thought it might just be my move constructor so I changed it to this:
	A(A &&b )  : number(std::move(b.number))
	{
		std::cout << "A:" << this << " moved from " << &b << std::endl;
	}


No difference.

This post has been edited by CTphpnwb: 31 August 2013 - 02:08 PM

Was This Post Helpful? 0
  • +
  • -

#3 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 31 August 2013 - 03:22 PM

Compiling this:
#include <iostream>
#include <string>
#include <vector>
#include <utility>

class A
{
public:
	int number;
	
	A(int n) : number(n)
	{
		std::cout << "A: " << number << " " << this << " created." << std::endl;
	}
	
	A(A&& b ) : number(std::move(b.number))
	{
		std::cout << "A:" << this << " moved from " << &b << std::endl;
	}
	
	A(const A & aIn)
	{
		std::cout << "A:" << this << " copied from " << &aIn << std::endl;
		number = aIn.number;
	}

	~A()
	{
		std::cout << "~A ("<< number << ") " << this << std::endl;
	}
	
	void Am_I_here()
	{
		std::cout << "A ("<< number << ") is here. " << this << std::endl;
	}
};

int main(int argc, const char * argv[])
{
	std::vector <A> myvector;
	for (size_t i = 0; i < 9; i++) {
		std::cout <<"push "<< i << std::endl;
		myvector.push_back(A(i));
		myvector[i].Am_I_here();
	}

	std::cout << "Testing existence of objects:"<< std::endl;
	for (size_t i = 0; i < myvector.size(); i++) {
		myvector[i].Am_I_here();
	}
	std::cout << "erasing"<< std::endl;
	
	myvector.erase(myvector.begin()+1);
	
	std::cout << "Finishing..."<< std::endl;
    return 0;
}


with the following command-line:

Quote

$ g++ -Wall -std=c++0x moveTest.cpp -o moveTest

I get no errors or warnings. I did change the loop variable types in main() because I got warnings about comparison between signed and unsigned integers.

This post has been edited by vividexstance: 31 August 2013 - 03:22 PM

Was This Post Helpful? 1
  • +
  • -

#4 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 31 August 2013 - 03:37 PM

Interesting. I get the same error with that code and I get a warning about converting i, an unsigned long to int (edit: maybe that was the warning you got?) in the push_back. Maybe it's my compiler settings?

This post has been edited by CTphpnwb: 31 August 2013 - 03:39 PM

Was This Post Helpful? 0
  • +
  • -

#5 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 31 August 2013 - 06:02 PM

View PostCTphpnwb, on 31 August 2013 - 06:37 PM, said:

Interesting. I get the same error with that code and I get a warning about converting i, an unsigned long to int (edit: maybe that was the warning you got?) in the push_back. Maybe it's my compiler settings?

With the code I posted, there were no errors or warnings. I only changed the i loop varaibles in main().
Was This Post Helpful? 0
  • +
  • -

#6 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 31 August 2013 - 07:11 PM

When you change the first i loop in main() you should get a warning about loss of precision here: A(int n) : number(n) . That's not what's worrying me though. It fails for me in exactly the same way my code failed.
Was This Post Helpful? 0
  • +
  • -

#7 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 01 September 2013 - 08:13 AM

What compiler are you using?
Was This Post Helpful? 0
  • +
  • -

#8 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 08:48 AM

I'm using Xcode with C++11 dialect and libc++(LLVM with C++11 support).
Was This Post Helpful? 0
  • +
  • -

#9 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 09:22 AM

I tried compiling from the command line using this as my makefile:
model: main.cpp 
	g++ -Wall -std=c++0x main.cpp -o moveTest
clean:
	rm moveTest.o 


and I got this:
$ make
g++ -Wall -std=c++0x main.cpp -o moveTest
cc1plus: error: unrecognized command line option "-std=c++0x"

I can't find a value for -std that it will accept. :(

Is anyone else seeing the same results I am? Same problem compiling?
Was This Post Helpful? 0
  • +
  • -

#10 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 01 September 2013 - 10:18 AM

What version of g++? Mine is 4.6.3, if it's newer than that then try -std=c++11 on the command-line.

*EDIT*: Move semantics weren't added until the C++11 update so if your compiler is older, that would be why you're getting errors. The standard library will be implemented differently depending on whether you're using the new standard update or not.

This post has been edited by vividexstance: 01 September 2013 - 10:20 AM

Was This Post Helpful? 0
  • +
  • -

#11 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 10:32 AM

Yes, it's older (4.2) , but Xcode's compiler isn't (it is 4.6.3) and it does compile there. I'll have to upgrade, but in the mean time, what did you get for output?

This post has been edited by CTphpnwb: 01 September 2013 - 10:33 AM

Was This Post Helpful? 0
  • +
  • -

#12 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 10:38 AM

I just found this so I tried this makefile:
model: main.cpp 
	clang++ -Wall -std=c++0x -stdlib=libc++ main.cpp -o moveTest
clean:
	rm moveTest.o 


and got this result:
/usr/bin/../lib/c++/v1/algorithm:1630:19: error: overload resolution selected implicitly-deleted copy
      assignment operator
        *__result = _VSTD::move(*__first);
                  ^
/usr/bin/../lib/c++/v1/algorithm:1654:12: note: in instantiation of function template specialization
      'std::__1::__move<A *, A *>' requested here
    return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
           ^
/usr/bin/../lib/c++/v1/__config:266:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
              ^
/usr/bin/../lib/c++/v1/vector:1552:29: note: in instantiation of function template specialization
      'std::__1::move<A *, A *>' requested here
    this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
                            ^
/usr/bin/../lib/c++/v1/__config:266:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
              ^
main.cpp:53:11: note: in instantiation of member function 'std::__1::vector<A, std::__1::allocator<A> >::erase'
      requested here
        myvector.erase(myvector.begin()+1);
                 ^
main.cpp:6:7: note: candidate function (the implicit copy assignment operator) has been explicitly deleted
class A
      ^
1 error generated.
make: *** [model] Error 1



That's pretty much what Xcode told me.
Was This Post Helpful? 0
  • +
  • -

#13 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 01 September 2013 - 11:55 AM

Are you including the <utility> header which has the std::move() function in it?

Here's the output from running the program:

Quote

./moveTest
push 0
A: 0 0xbffae1d4 created.
A:0x81eb008 moved from 0xbffae1d4
~A (0) 0xbffae1d4
A (0) is here. 0x81eb008
push 1
A: 1 0xbffae1d4 created.
A:0x81eb01c moved from 0xbffae1d4
A:0x81eb018 moved from 0x81eb008
~A (0) 0x81eb008
~A (1) 0xbffae1d4
A (1) is here. 0x81eb01c
push 2
A: 2 0xbffae1d4 created.
A:0x81eb030 moved from 0xbffae1d4
A:0x81eb028 moved from 0x81eb018
A:0x81eb02c moved from 0x81eb01c
~A (0) 0x81eb018
~A (1) 0x81eb01c
~A (2) 0xbffae1d4
A (2) is here. 0x81eb030
push 3
A: 3 0xbffae1d4 created.
A:0x81eb034 moved from 0xbffae1d4
~A (3) 0xbffae1d4
A (3) is here. 0x81eb034
push 4
A: 4 0xbffae1d4 created.
A:0x81eb050 moved from 0xbffae1d4
A:0x81eb040 moved from 0x81eb028
A:0x81eb044 moved from 0x81eb02c
A:0x81eb048 moved from 0x81eb030
A:0x81eb04c moved from 0x81eb034
~A (0) 0x81eb028
~A (1) 0x81eb02c
~A (2) 0x81eb030
~A (3) 0x81eb034
~A (4) 0xbffae1d4
A (4) is here. 0x81eb050
push 5
A: 5 0xbffae1d4 created.
A:0x81eb054 moved from 0xbffae1d4
~A (5) 0xbffae1d4
A (5) is here. 0x81eb054
push 6
A: 6 0xbffae1d4 created.
A:0x81eb058 moved from 0xbffae1d4
~A (6) 0xbffae1d4
A (6) is here. 0x81eb058
push 7
A: 7 0xbffae1d4 created.
A:0x81eb05c moved from 0xbffae1d4
~A (7) 0xbffae1d4
A (7) is here. 0x81eb05c
push 8
A: 8 0xbffae1d4 created.
A:0x81eb088 moved from 0xbffae1d4
A:0x81eb068 moved from 0x81eb040
A:0x81eb06c moved from 0x81eb044
A:0x81eb070 moved from 0x81eb048
A:0x81eb074 moved from 0x81eb04c
A:0x81eb078 moved from 0x81eb050
A:0x81eb07c moved from 0x81eb054
A:0x81eb080 moved from 0x81eb058
A:0x81eb084 moved from 0x81eb05c
~A (0) 0x81eb040
~A (1) 0x81eb044
~A (2) 0x81eb048
~A (3) 0x81eb04c
~A (4) 0x81eb050
~A (5) 0x81eb054
~A (6) 0x81eb058
~A (7) 0x81eb05c
~A (8) 0xbffae1d4
A (8) is here. 0x81eb088
Testing existence of objects:
A (0) is here. 0x81eb068
A (1) is here. 0x81eb06c
A (2) is here. 0x81eb070
A (3) is here. 0x81eb074
A (4) is here. 0x81eb078
A (5) is here. 0x81eb07c
A (6) is here. 0x81eb080
A (7) is here. 0x81eb084
A (8) is here. 0x81eb088
erasing
~A (8) 0x81eb088
Finishing...
~A (0) 0x81eb068
~A (2) 0x81eb06c
~A (3) 0x81eb070
~A (4) 0x81eb074
~A (5) 0x81eb078
~A (6) 0x81eb07c
~A (7) 0x81eb080
~A (8) 0x81eb084

This post has been edited by vividexstance: 01 September 2013 - 11:56 AM

Was This Post Helpful? 0
  • +
  • -

#14 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 02:09 PM

Yes, I pasted your code just as it was posted.

Your output is just as I had expected it to be. Too bad it's not working on mine. Maybe clang++ is lacking some C++11 support. Are you sure you aren't getting any warnings at all? Not even the unsigned long to int warning?
Was This Post Helpful? 0
  • +
  • -

#15 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: C++11 moves

Posted 01 September 2013 - 05:55 PM

After adding -Wextra to the command line these are the only warnings I'm getting:

Quote

g++ -Wall -Wextra -std=c++0x moveTest.cpp -o moveTest
moveTest.cpp:38:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
moveTest.cpp:38:5: warning: unused parameter ‘argv’ [-Wunused-parameter]

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3