6

Could somebody give me hints on why this code doesn't output anything? I'm assuming it has something to do with the move line...

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

int main(){ 
vector<int> v{66,79,154,24,76,13,7}; 

v = move(v); 
for(auto i: v) 
cout << i << " "; 
}

Update: So I added system("pause"); to help myself. Whether I need it or not is not what I'm focusing on. When I ran the code again in Visual Studio 2013, it worked. However, when I ran it through Ideone using C++14, it didn't output anything. Slightly confused now.

Visual Studio 2013 Ideone

N. O'Neil
  • 63
  • 4

2 Answers2

4

The standard library functions called with xvalue arguments may assume the argument is the only reference to the object; if it was constructed from an lvalue with std::move, no aliasing checks are made. In particular, this means that standard library move assignment operators do not have to perform self-assignment checks:

std::vector<int> v = {2, 3, 3};
v = std::move(v); // undefined behavior

For more detail please refer std::move and this question

Community
  • 1
  • 1
Shravan40
  • 8,922
  • 6
  • 28
  • 48
2

I will have to say it's unreproducible.

I used my Visual studio 2015 Update 3 and the output is normal :

66 79 154 24 76 13 7

Moreover, under VC++ implementation there is no problem moving the vector to itself:

_Myt& operator=(_Myt&& _Right)
        {   // assign by moving _Right
        if (this != &_Right)
            {   // different, assign it
            clear();

        if (_Alty::propagate_on_container_move_assignment::value
            && this->get_allocator() != _Right.get_allocator())
            {   // assign vector, dumping proxy
            this->_Free_proxy();
            this->_Myvec = _STD move(_Right._Myvec);
            this->_Alloc_proxy();
            }
        else
            this->_Myvec = _STD move(_Right._Myvec);


        this->_Mysize = _Right._Mysize;
        _Right._Mysize = 0;
        }
    return (*this);
    }

as you can see from the condition this != &_Right, the moving will only happen if you are not moving a vector to itself.

EDIT:

apparently the compiler which is used to compile "C++14" on Ideone (GCC?) decides to not check self-move assignment and decides to free the vector data. as we can see from this little experiment, after the move the vector size is 0. as said in other previous answers/comments, assigning a move to itself is implementation defined. I guess VC++ does the right thing in this case.

EDIT 2:

it appears that GCC really doesn't check for self asignment. it moves the vector data into a temporary one, and takes __x data, which in that point is already empty. man, sometimes GCC behaves stupidly just for sake of false sense performance ( because cmp + jz are really going to slow your program down? please.)

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • Just tested it on Ideone since I'm currently using my phone and forgot to open a compiler app which I have. Tried this again and it produced no output. Did you change or add anything? – N. O'Neil Feb 12 '17 at 14:53
  • when you get back, paste a screeshot of you see + tell us the exact compiler + version. and no, I didn't change anything. – David Haim Feb 12 '17 at 14:55
  • So based on your newest edit, I would assume that I should go based on what Visual Studio is showing me? – N. O'Neil Feb 12 '17 at 15:53
  • @N.O'Neil you should trust tests and QA only. never assume your code simply works. – David Haim Feb 12 '17 at 16:00