4 ms·
In general the compiler will not be able to prove that the value is not used again, because of possible aliasing. E.g. if you called a method on the object, the
by roca 7y ago
In general the compiler will not be able to prove that the value is not used again, because of possible aliasing. E.g. if you called a method on the object, then the compiler would need to be able to prove that 'this' hasn't been stashed away somewhere so it can be used again (without otherwise triggering undefined behavior) after the object has been moved out of.
I.e. to have the compiler prove absence of use-after-move requires the same sort of lifetime analysis it would need to prove absence of use-after-free, and that is simply not realistic for C++.
- olliej 7y agoUse after free (through references) is a standard problem in C++ through anything. But you can say post-move a value is dead, and use of existing references would be UB (sigh, but that isn't new). But to address your point: I'm a muppet and didn't think about conditional move in a loop. I had been thinking that you require that any conditional block has to end with a moved value int he same state - e.g. if (a) {move(x)} else {} The compiler would say both blocks must end with x being dead, so the else block would be required to call x.~X(); But yeah, that fails completely if you have for (...i...) { if (i) move(x) } because my clever rule means that x would have to die at the end of the first loop. But the general problem I have with std::move currently is that there's no guaranteed death - the fact that post std::move a destructor will still run, or the object can just continue to be used in general means that your code has to be made defensive against already being logically dead - even if just the destructor.
- roca 7y agoRust takes a conservative approach here --- you can't use x if it might have been moved along some control-flow path leading up to the current point. C++ could do that too. > Use after free (through references) is a standard problem in C++ through anything. But you can say post-move a value is dead, and use of existing references would be UB (sigh, but that isn't new). OK, arguably aliased-use-after-move could be treated as an existing form of UB. Sanitizers and static checkers would still need to be updated, however.