Hello, and welcome to C++ Weekly. I am your host,
Jason Turner. I am available for code reviews and on-site training. In this episode I'm going
to address a question maybe some of you have had, I don't know. It's just something that
I thought was interesting in a class that I was recently teaching, so let's dig into it.
[Music]
Now of course you know I gotta point you at the video description below so that you
can check out t-shirts, upcoming conference workshops. I'm going to be in Norway at NDC
TechTown this September 2023, and I'm hoping to give a workshop on C++ Best
Practices as well at CppCon in October in Aurora, Colorado. Now I want to state primarily here
that if you take any class from me, we are at some point going to address the
fact that you really should avoid 'move'. It's not that 'move' is inherently bad, but
if you can write code that doesn't actually need to move it's going to
be much better code than code that does need 'move'. So I'm going to start with
the one place where I say it's okay to use 'move' once you're done with my class. Now
I'm sure I'm going to get a bunch of comments about how you love 'move',
and I'm just going to tell you now that you're probably actually using it wrong
and you need to hire me to come to your company so that we can discuss all of this in person.
(I'm) going to add a few comments but this is the canonical case where 'move' is okay.
Really if you don't have invariance between your sub-objects you really probably should just
make them public - it simplifies so much code, results in faster compile times, faster code...
well, anyhow, all conversations for when you hire me to come out to your company.
Okay. Let's take this case. Now I'm doing the copy & move idiom. Now let's just say I have...
let's say I've got this.
I'm just going to default initialize this thing and pass it into my constructor. You might notice
that this 'move' is not really accomplishing anything because an array is a stack-based object,
therefore we cannot move the array itself. It's going to have to be copied. It doesn't have a
meaningful 'move' constructor in the case that we're talking about something like a string or
a vector. The point of the 'move' constructor is to just copy a pointer to a new location,
but since all of the data for the array lives on the stack there is no pointer to copy to a new
location, and you're correct if that's what you thought when you first saw this; however, it is
making an assumption about the type of the array. If I convert this to being an array of 42 strings
I need to consider the fact that moving the array now does a move operation on all of its
sub-objects in order, which means I'm getting a move of all of the strings,
not a copy. Let's just go ahead and see out of curiosity
if we can actually observe a difference here. It's allocating 42.
Let's see, this code is directly initializing 42 strings right here on the stack and then doing
a move of those 42 pointers into the local data object. That is conceptually what this is doing.
So if I were to remove this 'move',
then I get 50% more code generated because it's now having to call copy constructors
for each of these objects, which means it is now directly initializing this data_ again,
and now doing a copy of each of those 42 strings into the local data. So
just a random thought. So if you don't have invariance, you should probably just consider
making these things public. You should write code that avoids 'move', however in the case where you
know you need your own copy of the thing, then the copy & move idiom is a pretty good choice, and
there's actually a clang-tidy - modernize check for this specifically. The final point being...
So there you have it. If you do need to actually move an array for some reason,
like in this case of a constructor, it's probably smart to actually call std::move on it. Don't let
your intuition get in the way here, where you say, "Well, the array itself cannot be "moved"
so there's no reason to," you need to consider the fact that its sub-objects might be movable.
Well, thanks for watching this episode of C++ Weekly. I hope it was educational,
gave you something to think about. Be sure to subscribe and I'll see you next week.
[Music]