Search code examples
c++macosshared-ptrrvalue-reference

What is going on: C++ std::move on std::shared_ptr increases use_count?


I was always assuming that std::move() on a std::shared_ptr steals the pointer and sets the pointer of the original to nullptr-thus not increasing the reference count. That does not seem to be true in my world.

SETUP:

MacOS, g++ -version => "Apple LLVM version 10.0.1 (clang-1001.0.46.3)"

CODE:

#include <cstdio>                                                                                                                                                                                  
#include <memory>
class Thing { public: Thing(int N) : value(N) {} int value; };

void print(const char* name, std::shared_ptr<Thing>& sp)
{ printf("%s: { use_count=%i; }\n", name, (int)sp.use_count()); }

int main(int argc, char** argv) {
    std::shared_ptr<Thing>  x(new Thing(4711));
    print("BEFORE x", x);
    std::shared_ptr<Thing>  y = std::move(x);
    y->value = 4712;
    print(" AFTER x", x);
    print(" AFTER y", y);
    return 0;
}

OUTPUT:

Compiling (g++ tmp.cpp -o test), and running (./test), delivers

BEFORE x: { use_count=1; }
 AFTER x: { use_count=2; }
 AFTER y: { use_count=2; }

So, the reference count is increased while using std::move().

QUESTION:

What is going on, here?


Solution

  • What is going on, here?

    On MacOS, it seems that you must explicitly enable move-sematics with -std=c++11 (or later standards)¹. Otherwise, the example happens to compile (i.e., std::shared_ptr from the related library implementation is usable) but doesn't work correctly as the required language features aren't enabled. This results in actual copies being made instead of move constructions. It would have been better if the AppleClang package didn't even allow an instantiation of std::shared_ptr when the required language features isn't enabled.

    ¹) Thanks to @t.niese for testing the given compiler/platform.