17

Possible Duplicate:
What can I do with a moved-from object?

After you called std::move and passed the result to a function, you generally have to assume that accessing the moved object later will result in undefined behavior.

Are there tools that can detect those accesses and warn you. For example:

{
  Widget w;
  foo(std::move(w));
  // w may be undefined at this point

  w.doSomething(); // WARN
}

At least, gcc 4.7.2 and clang 3.2 with -Wall do not complain.

Update: Looking back at this question, the critical point is that the compiler cannot decide whether an object is still valid after it has been moved from. If the proposal N4034: Destructive Move was accepted, I would expect the compiler to have more options (but only if the move is destructive).

Community
  • 1
  • 1
Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239
  • 2
    Are you sure it results in undefined behavior? My understanding was that the object is in a valid but unspecified state, which might not lead to UB. – templatetypedef Jan 27 '13 at 21:50
  • @templatetypedef I'm not sure. I just wanted to ask that as a separate question, but it has been asked before: http://stackoverflow.com/questions/8522740/is-the-state-of-any-standard-class-after-being-moved-specified – Philipp Claßen Jan 27 '13 at 21:52
  • 5
    It's not UB. The specifics have to be documented by your class, though. – Kerrek SB Jan 27 '13 at 21:52
  • 7
    @JesseGood: I don't think this is a duplicate. He seems to know what he can do, he just wants some diagnostics to make sure he's not doing it. But in the general case I don't think this makes sense I believe – Andy Prowl Jan 27 '13 at 21:56
  • @JesseGood Thanks, the question is related and helpful for me. But I asked for tool support, so I don't consider it a duplicate. – Philipp Claßen Jan 27 '13 at 21:56
  • 2
    *"accessing the moved object later will result in undefined behavior"* - And, as others have said, exactly this assumption is wrong, which in turn is the reason why a general warning about accessing a moved from object doesn't make sense, since the compiler alone doesn't know which methods of the object are safe to access after a move. – Christian Rau Jan 27 '13 at 22:29
  • 1
    @PhilippClaßen: You asked for tool support. But warnings are wrong, because there's no way for the compiler to know. Using a moved from object is not a priori wrong. It's not even wrong in most cases; it's a legitimate thing to do, and the compiler shouldn't warn for it. – Nicol Bolas Jan 27 '13 at 22:57
  • If it were UB to access a moved-from object, then it would be impossible to ever run their destructors. – GManNickG Jan 28 '13 at 04:46
  • Would love to have a Destructive Move feature! For now, to avoid headaches, I might, in the meantime, end up giving up the otherwise so handy idea of explicitly move-ing stuff at all :-( – FlorianH Jun 29 '20 at 09:54

1 Answers1

15

Nor should they. The behavior of a moved-from class is whatever you want it to be. It is not something that a compiler should be warning about.

For standard library objects, a moved-from class is in a "valid but unspecified state". As such, it is perfectly legal to do this:

std::vector<int> v{20, 30, 40};
std::vector<int> v2 = std::move(v);
v = std::vector<int>{50, 60, 70, 80};

clear doesn't care what the current state of the vector is; it just clears the vector. Thus it is reset to a known state. Similarly, operator= doesn't care what the current state is; it will reset it to a known state.

Dev Null
  • 4,731
  • 1
  • 30
  • 46
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 2
    Granted, this usage should be safe, but you are reinitializing the object (operator=). So what if you have called `v.size()` instead. I don't know if it is guaranteed to return 0, so I still think a warning would be a good idea here. – Philipp Claßen Jan 27 '13 at 22:01
  • 2
    `v.size()` is not guaranteed to return 0, but return the actual size of the container. In some cases an attempted move could turn out to be a copy, and the source might be unchanged. For example, moving from an `int` will likely *not* make the source have a zero value. – Bo Persson Jan 27 '13 at 22:13
  • 1
    @PhilippClaßen Well, `size` may not be guaranteed to return `0`, but neither is it UB to call `size` and work with its return value. The compiler just doesn't know enough about your use case of the object or about the preconditions of its methods to say that you're at error when accessing it. I don't want warnings for obviously correct and perfectly defined (by standard) code just because the compiler thinks I'm stupid. – Christian Rau Jan 27 '13 at 22:32
  • 1
    @PhilippClaßen But Ok, in case of the standard library components, the compiler could indeed know about the preconditions of their methods and could really warn when accessing methods that require a certain defined state (like `front` or `pop_back`) after a move. But this may be a bit high a demand from the compiler and, even more important, would require the standard library to be supported by *"compiler magic"* apart from being mere library components (and wouldn't work for custom types, anyway). – Christian Rau Jan 27 '13 at 22:38