C++ frequently failed interview question
As we all know, the whole IT world and all those fancy technologies we use daily are changing at a breakneck pace. The same thing goes with the programming languages like C++, which has been evolving pretty fast since 2011.
C++11 or even C++14 standard is currently widely used in various production environments. Therefore, it's not a surprise that IT technical interviewers (myself included) are struggling to check if all the candidates know all the ins and outs of aforementioned standards. Alright, but let's cut to the chase now!
Move semantics is considered as one of the most important features introduced in C++11. Therefore, during almost every job interview I have a pleasure to participate in as a technical interviewer, I ask a simple, yet very interesting question, namely:
What is move semantics - what does std::move
method do?
And this is the moment where the party is started. The vast majority of candidates start their answers with:
It moves underlying memory/reference pointers from one object to another... ".
When I hear this kind of answers, an example of code springs to my mind in a snap, and I try to put it on a piece of paper in front of the interviewed person:
std::vector< int > vec{1,2,3,4,5};
auto mvec = std::move(vec);
std::cout << vec.size() << std::endl;
std::cout << mvec.size() << std::endl;
Then I go on to explain that this is a very simple piece of code - two lines of printed out values, one vector of int
s declared and initialized with five values, and one line with std::move
in charge, as a nice add-on.
As a very next step after such a nice introduction, I ask the candidate to answer yet another question:
Will the code compile?
The vast majority of hopefuls goes with quite a firm statement:
Yes, it will compile!
Alright Captain Obvious, it will compile indeed. Good answer - This is what I think to myself, then I provide a follow up question:
Will the code work as it is intended?
This is the moment where an eyebrow is raised and all the doubts happen to appear. How it can work, when just a few minutes ago, I said that the memory will be moved, so the vec variable will be invalidated. This is one of the most common answers. So, I'm trying to push again:
But how it can invalidate the stack memory?
After such amount of problematic questions, a lot of people just throw in the towel, since they don't have any other idea of the possible solution in their minds. Seems they thought they knew how the infamous std::move
method works, but apparently they have no idea what std::move
is at all.
No worries, though. I will answer this pain-in-the-neck kind of question for you - as I do for every candidate.
std::move
is only a remove-reference-cast-to-rvalue operation, so basically it's intended only to ensure that the move constructor - if such exists on the left side - should be called with the argument from the right side. As simple as that.
Coming back to our example - the move constructor of mvec
variable is called with vec
variable as an argument. Move steals the internal memory objects, as the vector inside consists of three-pointers:
- _M_start
which is nullptr
- _M_finish
which is nullptr
- _M_end_of_storage
which is nullptr
Alright, but let's just stop here for a bit. What the heck it means that it steals or moves? Let's dispel all the doubts now - this is what move constructor should do and is doing:
swap the data (not assign, not copy but swap) which is the fastest way. Thus the old vector starts to be empty and the new vector has elements from the old one. This is why the deallocation of both vectors will work as if the properly allocated pointers existed still only in one place.
Got it now? Yep, now it sounds like a pretty simple thing, right?