Comment by knorker

Comment by knorker 6 hours ago

1 reply

The call to a move cons/move assign does not happen at call time. When a function taking rvalue reference is called, it can still have two code paths, one that copies the argument, and one that moves it.

All the && does is prevent lvalues from being passed as arguments. It's still just a reference, not a move. Indeed, in the callee it's an lvalue reference.

But yeah, you can statically check if there exists a code path that calls the copy cons/copy assign. But you'll need to check if the callee calls ANY type's copy cons/assign, because it may not be the same type as the passed in obj.

At that point, what even is a move? char*p = smartptr.release() in the callee is a valid move into a raw pointer, satisfying the interface in callee. That's a move.[1] how could you detect that?

[1] if this definition of move offends you, then instead remember that shared_ptr has a constructor that takes an rvalue unique_ptr. The move only happens inside the move constructor.

How do you detect all cases of e.g. return cons(ptr.release()) ? It may even be the same binary code as return cons(std::move(ptr))

Probably in the end shared pointer constructor probably calls .release() on the unique ptr. That's the move.

Yup. That's what https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_p... says.

(Sorry, on phone so not full code. Hopefully I stopped autocorrect all times it interfered)

charcircuit 3 hours ago

What the callee does it out of scope. We are talking about a single assignment or construction of a variable. This has nothing to do with tracing execution. It happens at one place, and you can look at the place to see if it is using a copy or move contructor.