Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I assign 0 to a shared_ptr? Why?

Tags:

c++

null

c++11

I realized the following compiles fine in GCC 4.7:

#include <memory>

int main() {
    std::shared_ptr<int> p;
    p = 0;
}

However, there is no assignment operator from int or from int*, and there is no implicit constructor from either int or int* either. There is a constructor from int*, but that one is explicit. I checked the standard library implementation and the constructor is indeed explicit, and no fishy assignment operators are in sight.

Is the program actually well-formed or is GCC messing with me?

like image 386
R. Martinho Fernandes Avatar asked Aug 09 '12 17:08

R. Martinho Fernandes


1 Answers

The reason this works is this short quote from the standard:

§4.10 [conv.ptr] p1

A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. [...] A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t. [...]

And the fact that std::shared_ptr has an implicit constructor from std::nullptr_t:

§20.7.2.2 [util.smartptr.shared] p1

constexpr shared_ptr(nullptr_t) : shared_ptr() { }

This also allows for oddities like this:

#include <memory>

void f(std::shared_ptr<int>){}

int main(){
  f(42 - 42);
}

Live example.

like image 183
Xeo Avatar answered Oct 03 '22 09:10

Xeo