Hacker News new | ask | show | jobs
by UncleMeat 2118 days ago
> BTW.. in his example - just use move semantics, put the pointer as the 5th argument, and you'll probably have the same runtime cost

He talks about this. C++ doesn't have destructive moves like rust does, which is the root cause of why you cannot make the unique_ptr cost zero. It'd take an ABI change to fix this. This is precisely why the scenario is interesting. A lot of people (including you) thought that "just use move semantics" would solve it.

2 comments

Thing is... talks like these give a wide body of application developers ammunition to say "smart pointers are slow, we need to use raw pointers!". Which is incredibly damaging. In many real-life situations, the difference literally doesn't matter (one more memory move? pfft... I'd take the whole complicated, exception-safe function body over knowing that in case of an exception I won't have a memory leak)

There are indeed cases where this sort of difference in performance matters; But those are a vanishingly small group of people; and as far as those people are concerned - they typically look at assembly anyway.

> smart pointers are slow, we need to use raw pointers!

He addresses this in the QA at the end. Chandler explicitly says "I still believe you should use unique_ptr and pass it by value". If somebody watches this video and takes away "don't use smart pointers" then they weren't paying attention.

I've been wondering why they don't permit destructor elision after a move into a newly constructed parameter. I have a hard time seeing how this would break reasonable code, and even then, we can probably find a backward compatible workaround (or rely on a compiler flag). Any idea?
ABI. C++ defines rigorous calling conventions that don't permit this. There are some on the committee who want to permit ABI breaks to enable these sorts of optimizations (in this case, destructive-move) but the committee in general has been super hesitant to permit ABI breaks.

It won't break reasonable code. The problem is it breaks interop with compiled binaries.

I'm confused, this seems unrelated to ABI. It's entirely up to the caller whether to subsequently destroy the moved-from object or to skip doing so. Whether or not the caller does so is irrelevant to the call or how the parameter gets passed, and it wouldn't affect the moved-to object (whose destructor always runs). The destruction of the moved-from object (if not elided) happens long after the call has returned - at the end of the object's scope.

I think you're confusing my proposal with the pass-in-register proposal? Or maybe I'm missing something.