Message from C, C++ talks

June 2019

— /Qt

— Hi, I'm learning cpp and reading about move semantics, consider this two functions:

— I have put log messages in all move/copy operations

— If I execute f or g, both prints saying the copy constructor is being used, which is kind of what would have expected

Message permanent page


However, in g, as a is not being used again, I would've tought the compiler would optimize this, and use the move constructor instead of the copy one

— So my question is, is there a reason why the compiler didn't optimize this? are there some side effects I should be aware of?

Message permanent page

— Think of an rvalue as something that doesn't have a name. Your variable has a name, "a", so when you initialize b, the compiler sees a as an lvalue, therefore calling the copy constructor instead of the move one

Message permanent page

— That's why utilities like std::move or std::forward exist

— The compiler cannot take an lvalue and say "well, this is clearly not used again, so what if we take as an rvalue and call the move constructor?". Maybe someone can implement that optimization, but doing that for every variable that it's initialized with a previous one will certainly increase the compile times

Message permanent page

— Just use std::move everytime you know that variable is not going to be used again to enable the move semantics

Message permanent page

— Ohh ok. So it is not worth optimizing, given things like std::move exist. Which is indeed more explicit

Message permanent page

— I passed -O3 to g++, can I ask, how do you know there are no calls to the move/copy constructors?

— Look at the generated assembly

— Woa, not there yet hahaha

— But do note, using std::move everywhere can actually do harm. E.g. it can prevent the compiler from doing copy ellisions

Message permanent page