1
std::string s1 = "hello";
std::string s2 = std::move(s1);
std::string s3 = std::string("hello");
std::string &&r3 = std::move(s3);
std::string s4{r3};

The compiler I use is g++ 7.5.0. The compile command is g++ -Wall -g source.cpp. I use gdb to see which constructor is called. I think only s2 calls the move constructor and the others use copy constructor. Am I right? Would you like to tell me why?

aisv
  • 21
  • 4
  • The compiler will probably avoid all code here because there's no side effects. You could always compile with `-fno-elide-constructors` flag and do some `cout`s in the constructors and see what you get. If no constructors are eldided I'd agree that `s2` will be a move construction (but dangerous, because `s1` isn't dealt with), same with `r3`. – Elliott Aug 07 '21 at 08:47
  • If you're confused with how `move` semantics actually works, it's very, very simple. [Here's my explanation](https://stackoverflow.com/questions/64331419/why-not-destory-after-calling-stdmove/64335967#64335967) – Elliott Aug 07 '21 at 08:48
  • @Elliott Thanks for your suggestion ```-fno-elide-constructors```, I will try again. – aisv Aug 07 '21 at 09:28
  • @utree I made a small test program that shows the behavior in C++11, 14, 17 and 20 when you use `-fno-elide-constructors`. That should show the behavior described in the answer you've gotten. [Here it is](https://godbolt.org/z/czj9ePfeE) – Ted Lyngmo Aug 07 '21 at 09:41
  • @Elliott: what do you mean, `s1` isn't dealt with? It will become the empty string. What's dangerous about that? – TonyK Aug 07 '21 at 11:53
  • @TonyK Maybe, he means that if I call `std::move(s1)` to initialize `s2` , then I can't use `s1` anymore. – aisv Aug 09 '21 at 04:14
  • @utree: You certainly can use `s1` after it's been moved from -- there is nothing "dangerous" about it. It remains a valid string (albeit an empty one). – TonyK Aug 09 '21 at 10:09

1 Answers1

2

s2 and s3 "use" move constructor in C++11. s3 no longer uses move constructor in C++17.

s1 uses the constructor that accepts a pointer and s4 "uses" copy constructor.

By "use", I mean that the constructor is used by the abstract machine. Moves and copies may be elided away by a smart optimiser, and function calls including constructors can be expanded inline, in which cases you won't see them in a debugger.

eerorika
  • 232,697
  • 12
  • 197
  • 326