labath added inline comments.
================
Comment at:
lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h:235-245
PythonObject &operator=(const PythonObject &other) {
Reset(PyRefType::Borrowed, other.get());
return *this;
}
- void Reset(PythonObject &&other) {
+ PythonObject &operator=(PythonObject &&other) {
Reset();
----------------
lawrence_danna wrote:
> labath wrote:
> > lawrence_danna wrote:
> > > labath wrote:
> > > > lawrence_danna wrote:
> > > > > labath wrote:
> > > > > > lawrence_danna wrote:
> > > > > > > labath wrote:
> > > > > > > > You can consider simplifying this further down to a
> > > > > > > > "universal"/"sink" `operator=(PythonObject other)`. Since the
> > > > > > > > object is really just a pointer, the extra object being created
> > > > > > > > won't hurt (in fact, the removal of `&`-indirection might make
> > > > > > > > things faster).
> > > > > > > wouldn't that result in an extra retain and release every time a
> > > > > > > PythonObject was copied instead of referenced or moved?
> > > > > > No, it shouldn't, because the temporary PythonObject will be
> > > > > > move-constructed (== no refcount traffic), if the operator= is
> > > > > > called with an xvalue (if the rhs was not an xvalue, then you
> > > > > > wouldn't end up calling the `&&` overload anyway). Then you can
> > > > > > move the temporary object into *this, and avoid refcount traffic
> > > > > > again.
> > > > > >
> > > > > > So, there is an additional PythonObject created, but it's
> > > > > > move-constructed if possible, which should be efficient, if I
> > > > > > understand these classes correctly. This is the recommended
> > > > > > practice (at least by some) when you don't want to squeeze every
> > > > > > last nanosecond of performance..
> > > > > How do you move the temporary object into *this, if you only have
> > > > > `operator=(PythonObject other)` to assign with?
> > > > In case that wasn't clear, the idea is to replace two operator=
> > > > overloads with a single universal one taking a temporary. The advantage
> > > > of that is less opportunities to implement move/copy incorrectly. The
> > > > cost is one temporary move-constructed object more.
> > > so does that amount to just deleting the copy-assign, and keeping the
> > > move-assign how it is?
> > > How do you move the temporary object into *this, if you only have
> > > operator=(PythonObject other) to assign with?
> >
> > You need to do it manually, like the current `&&` overload does, but you
> > don't also need to implement the copy semantics in the const& overload.
> >
> > > so does that amount to just deleting the copy-assign, and keeping the
> > > move-assign how it is?
> > Almost. The implementation of move-assign would remain the same, but you'd
> > drop the `&&` (otherwise you'd lose the ability to copy-assign) from the
> > signature. I.e.,
> > ```
> > PythonObject &operator=(PythonObject other) {
> > Reset();
> > m_py_obj = std::exchange(other.m_py_obj, nullptr); // I just learned of
> > this today so I have to show off.
> > return *this;
> > }
> > ```
> oooooooh, i get it. It didn't occur to me that you could treat other as a
> rvalue without passing it as one in the parameter list, but of course you can
> because if it's pass-by-value then it's just a local variable by the time
> operator= gets its hands on it.
Yeah, isn't c++ fun? :)
I actually think this is one of the best features of c++11, as it allows you to
write a single function that takes ownership of something more-or-less
efficiently without any superfluous overloads or fancy `&&`s. The only problem
is overcoming the learned "wisdom" that `const &` is the most efficient way to
pass objects around.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69080/new/
https://reviews.llvm.org/D69080
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits