The Move That Wasn’t
While trying to duplicate the results I measured in my “Time To Get Moving!” post, an astute viewer posted this comment:
For your convenience, I re-list the code in question here for your inspection:
#include <iostream> #include <vector> #include <utility> #include <chrono> using namespace std; struct Msg{ vector<double> vDoubs; Msg(const int NUM_ELS) : vDoubs(NUM_ELS){ } }; int main() { //Construct a big Msg object! const int NUM_ELS = 10000000; Msg msg1{NUM_ELS}; //reduce subsequent code verbosity using std::chrono::steady_clock; using std::chrono::duration_cast; using std::chrono::microseconds; //Measure the performance of //the "free" copy operations auto tStart = steady_clock::now(); Msg msg2{msg1}; //copy ctor msg1 = msg2; //copy assignment auto tElapsed = steady_clock::now() - tStart; cout << "Copy ops took " << duration_cast<microseconds>(tElapsed).count() << " microseconds\n"; //Measure the performance of //the "free" move operations tStart = steady_clock::now(); Msg msg3{std::move(msg1)}; //move ctor msg1 = std::move(msg3); //move assignment tElapsed = steady_clock::now() - tStart; cout << "Move ops took " << duration_cast<microseconds>(tElapsed).count() << " microseconds\n"; cout << "Size of moved-from object = " << msg3.vDoubs.size(); } //"free" dtor is executed here for msg1, msg2, msg3
Sure enough, I duplicated what my friend Gyula discovered about the “move” behavior of the VS2013 C++ compiler:
Intrigued by the finding, I dove deeper into the anomaly and dug up these statements in the fourth edition of Bjarne Stroustrup’s “The C++ Programming Language“:
Since the Msg structure in the code listing does not have any copy or move operations manually defined within its definition, the compiler is required to generate them by default. However, since Bjarne doesn’t state that a compiler is required to execute moves when the programmer explicitly directs it to with std::move() expressions, maybe the compiler isn’t required to do so. However, common sense dictates that it should. Hopefully, the next update to the VS2013 compiler will do the right thing – like GCC (and Clang?) currently does.
Testing the code in the up-to-date beta web compiler for visual C++ (http://webcompiler.cloudapp.net/), the results looks good. So it is indeed fixed for next time.
I just replicated your result. Nice. I didn’t even know about that web compiler. Thanks!