7

Suppose there is a function like this:

int * func()
{
  std::unique_ptr<int> ptr(new int(3));
  //Few more lines of code

  //then one function added where programmer writes like some thing

  SOME_OTHER_FUNC(std::move(ptr));

  return ptr.get();
}



void SOME_OTHER_FUNC(std::unique_ptr<int> arg_ptr)
{
}

Is there a way to warn programmers to avoid such mistakes with std::move? This is not about unique_ptr only but for other objects too.

Is there any mechanism to generate a warning when we used a moved-from object inappropriately?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
gaurav bharadwaj
  • 1,669
  • 1
  • 12
  • 29
  • not sure if duplicate but close topic wise: http://stackoverflow.com/questions/39413502/why-should-a-move-constructor-or-move-assignment-operator-clear-its-argument/39413587#39413587 – Hayt Oct 05 '16 at 14:50
  • 1
    I expect compiler writers to invent a warning for the use of anything that has been cast to an rvalue, such as by `std::move`. If it hurts you enough, consider submitting a patch to your compiler's author! – Toby Speight Oct 05 '16 at 14:53
  • @TobySpeight I'm sceptical that such warning would be introduced. Types can have move constructors / assignment operators that leave the original in a (partially, or even entirely) specified state and certain (maybe even all) operations would have well defined behaviour. How could the compiler know whether the use of moved from object was unintentional? – eerorika Oct 05 '16 at 16:17
  • Possible duplicate of [Warning when rvalue-declared variable goes out of scope being not moved from](http://stackoverflow.com/questions/36152183/warning-when-rvalue-declared-variable-goes-out-of-scope-being-not-moved-from) – Tomilov Anatoliy Oct 06 '16 at 01:49
  • 2
    Cite from LLVM Weekly: A new `clang-tidy` check, *misc-use-after-move* has been introduced. This warns if an object is used after it has been moved [r281453](http://reviews.llvm.org/rL281453). – Tomilov Anatoliy Oct 06 '16 at 02:00

3 Answers3

15

std::move is the warning. If your programmers don't understand this, you have to educate them better. If the function is so long that the programmer can reasonably overlook the move, you need to refactor your function to make it shorter.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • 2
    Or, limit the scope of the `move`'d from variable, so its lifetime ending and beginning is right next to where it is moved from. – Yakk - Adam Nevraumont Oct 05 '16 at 14:45
  • 1
    "*`std::move` is the warning.*" What's said is that the committee went through a very great deal of trouble to *force* you to use `std::move` to make sure that it would be clear to everyone reading the code that the object has been moved from. And some people still don't get it. – Nicol Bolas Oct 05 '16 at 15:22
  • 1
    @NicolBolas Everyone knows that `std::move` does not move, and `std::forward` does not forward. – Yakk - Adam Nevraumont Oct 05 '16 at 15:31
0

Not every problem can, or should, be solved within source code.

  1. Using unique_ptr is an implementation detail; encapsulate it.

  2. Specify pre and post conditions for the function and use tests.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
knivil
  • 787
  • 3
  • 11
  • 3
    Not every problem is solved by abstraction. The fact that your resource can be moved-from and becomes invalid afterwards cannot be solved by abstraction. Perfect tests and test coverage solve everything in the same way that writing perfect code solves everything. More perfect tests and more perfect code make things better, but saying "write tests to cover this" is about as useful as "don't do it in the first place". – Yakk - Adam Nevraumont Oct 05 '16 at 17:44
0

It would be nice to have the compiler help, wouldn't it? There are good reasons it's not as simple as you might think:

  1. std::move() isn't magic, and you could write a similar function of your own. How would the compiler know that your new function has to be treated the same way? You'd need a standard attribute with which to decorate the function. If you make the warning specific to the exact function std::move, you encode knowledge of the standard library into the language compiler¹.
  2. Although in general, a moved-from object can only be assigned to or destructed, some classes may give stronger guarantees about the moved-from state (for example, a container could be documented as becoming a valid empty collection when moved from). How can you tell the compiler which operations are safe on specific moved-from objects like that?

¹ Counter-argument: compilers already do something similar, of course, when validating format strings for std::printf() and std::scanf() families of functions.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103