views:

1876

answers:

6

Most of C++ programmers are waiting for C++0x. An interesting feature and a confusing one (at least for me) is the new nullptr.

Well, no need anymore for the nasty macro NULL.

int* x = nullptr;
myclass* obj = nullptr;

Still, I am not getting how nullptr works. For example, Wikipedia article says:

C++0x aims to correct this by introducing a new keyword to serve as a distinguished null pointer constant: nullptr. It will be of type nullptr_t, which is implicitly convertible and comparable to any pointer type or pointer-to-member type. It is not implicitly convertible or comparable to integral types.

How is it a keyword and an instance of a type?

Also, do you have another example (beside the Wikipedia one) where nullptr is superior to good old 0?

+1  A: 

Well, other languages have reserved words that are instances of types. Python, for instance:

>>> None = 5
  File "<stdin>", line 1
SyntaxError: assignment to None
>>> type(None)
<type 'NoneType'>

This is actually a fairly close comparison because None is typically used for something that hasn't been intialized, but at the same time comparisons such as None == 0 are false.

On the other hand, in plain C, NULL == 0 would return true IIRC because NULL is just a macro returning 0, which is always an invalid address (AFAIK).

Mark Rushakoff
+2  A: 

It is a keyword because the standard will specify it as such. ;-) According to the latest public draft (n2914)

2.14.7 Pointer literals [lex.nullptr]

pointer-literal:
nullptr

The pointer literal is the keyword nullptr. It is an rvalue of type std::nullptr_t.

It's useful because it does not implicitly convert to an integral value.

KTC
+4  A: 

nullptr: A Type-safe and Clear-Cut Null Pointer

The new C++09 nullptr keyword designates an rvalue constant that serves as a universal null pointer literal, replacing the buggy and weakly-typed literal 0 and the infamous NULL macro. nullptr thus puts an end to more than 30 years of embarrassment, ambiguity, and bugs. The following sections present the nullptr facility and show how it can remedy the ailments of NULL and 0.


Another good reference at WikiBooks: More C++ Idioms/nullptr
With sample code.


Here at Stackoverflow:
Do you use NULL or 0 (zero) for pointers in C++?


Other references.

nik
+19  A: 

How is it a keyword and an instance of a type?

This isn't surprising. Both true and false are keywords and as literals they have a type ( bool ). nullptr is a pointer literal of type std::nullptr_t, and it's an rvalue (you cannot take the address of it using &).

  • 4.10 about pointer conversion says that an rvalue of type std::nullptr_t is a null pointer constant, and that an integral null pointer constant can be converted to std::nullptr_t. The opposite direction is not allowed. This allows overloading a function for both pointers and integers, and passing nullptr to select the pointer version. Passing NULL or 0 would confusingly select the int version.

  • A cast of nullptr_t to an integral type needs a reinterpret_cast, and has the same semantics as a cast of (void*)0 to an integral type (mapping implementation defined). A reinterpret_cast cannot convert nullptr_t to any pointer type. Rely on the implicit conversion if possible or use static_cast.

  • The Standard requires that sizeof(nullptr_t) be sizeof(void*).

Johannes Schaub - litb
Oh, after looking, it seems to me that the conditional operator can't convert 0 to nullptr in cases like `cond ? nullptr : 0;`. Removed from my answer.
Johannes Schaub - litb
I got it man. Your true )
AraK
Note that `NULL` is not even guaranteed to be `0`. It can be `0L`, in which case a call to `void f(int); void f(char *);` will be ambiguous. `nullptr` will always favor the pointer version, and never call the `int` one. Also note that `nullptr` *is* convertible to `bool` (the draft says that at `4.12`).
Johannes Schaub - litb
@litb: so regarding f(int) and f(void*) - will f(0) still be ambiguous?
Steve Folly
@Steve, no that will call the `int` version. But `f(0L)` is ambiguous, because `long -> int` aswell as `long -> void*` is both equally costly. So if NULL is `0L` on your compiler, then a call `f(NULL)` will be ambiguous given those two functions. Not so with `nullptr` of course.
Johannes Schaub - litb
+1  A: 

When you have a function that can receive pointers to more than one type then calling it with NULL is ambiguous, the way this is worked around now is very hacky by accepting an int and assuming it's NULL (case in point)

template <class T>
class ptr {
    T p_;
    public:
        ptr(T* p) : p_(p) {}

        template <class U>
        ptr(U* u) : p_(dynamic_cast<T*>(u)) { }

        // Without this ptr<T> p(NULL) would be ambiguous
        ptr(int null) : p_(NULL)  { assert(null == NULL); }
};

In C++0x you would be able to overload on nullptr_t so that ptr<T> p(42); would be a compile-time error rather than a run-time assert.

 ptr(std::nullptr_t) : p_(nullptr)  {  }
Motti
+2  A: 

Channel9 posted a video interview with a Microsoft developer on nullptr support in Visual Studio 2010.

Anonymous Coward