Hacker News new | ask | show | jobs
by petters 2326 days ago
What is the "runtime overhead involved in passing unique_ptr by value"?

The reference is a 1h YouTube video.

4 comments

Short version: it passes a pointer to the pointer forcing a double indirection rather than a single.

Simple attempts to fix don't really work. Not even sure an ABI break will be enough, but it would at least be a minimum requirement.

The standard would probably need to introduce destructive move semantics and trivially relocatable types (unique_ptr for example) to enable simplifying the ABI for such types. Then of course an ABI break is required to actually apply the changes.
Makes me wonder why anybody takes them by value, and not by rvalue-reference.

But unique_ptr in public interfaces feels like code smell. I have done it, but not proudly.

Quite a few times, I've made C++ library APIs like this:

    struct iface
    {
        virtual ~iface(){ }
        virtual void doSomething() = 0;
        static std::unique_ptr<iface> create();
    }
I don't know good ways to replace unique_ptr here.

Requiring library users to #include the concrete implementation is not good: inflates compilation time, pollutes namespaces, pollutes IDE's autocompletion DB.

Can go C-style i.e. pass double pointer argument to the factory, or return raw pointer. But then user needs to remember to destroy the object.

Returning them by value is fine. *RVO avoids inefficiencies.

But it would often be better to make a move-only value type, and return that instead.

Seriously: if you have to pass its address regardless, why pay to construct and destroy another one that you only wanted to std::move out of anyway?
The video: https://www.youtube.com/watch?v=rHIkrotSwcc

I wrote up a reddit post for a possible workaround for removing the overhead. It's standard C++, no ABI break is required. It's not without caveats though: https://www.reddit.com/r/cpp/comments/do8l2p/working_around_...

It's the overhead VS. passing a raw pointer. The itanium ABI says that std::unique_ptr has to be passed by address due to its special member functions (the ABI doesn't know if it stores a pointer to itself).

Compilers have an attribute to remove this overhead, but it's an ABI break to do it.

Thanks, I always assumed that a unique ptr was identical to a regular pointer under the hood.