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?
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 typestd::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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With