次の方法で共有


C++0x features in VC2010 - nullptr

Summary Page

 

(n3090.pdf is the current working draft of C++0x standard, it is available at https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3090.pdf)

What we have before C++0x

Everyone knows that null pointer value is NULL. In C++, NULL is defined as follows:

#define NULL 0

One interesting thing about '0', it can be converted to any pointer types. However, this is not true for 0’s underlying type 'int'.

This leads to big problem when template is involved. For example (It is simplified from std::make_shared):

template <typename T>

struct CtorWrapperUnary

{

    template<typename U> T *operator()(U u)

    {

        return new T(u);

    }

};

struct A {

    A(int *) {}

};

void bar()

{

    CtorWrapperUnary<A> f;

    f(0); // error C2664: 'A::A(int *)' : cannot convert parameter 1 from 'int' to 'int *'

}

The functor "CtorWrapperUnary" wraps the constructor of A. However, the functor can’t accept argument '0' while A’s constructor can. The root cause is that the special property of '0' is lost when it is converted to a variable 'u' of type 'int'.

What we have now in C++0x

To solve the above problem, we have to have a type which can be converted to any pointer types.

In C++0x, this type is std::nullptr_t, and nullptr is a keyword which has value of this type.

With nullptr, we can rewrite the code as:

void bar()

{

    CtorWrapperUnary<A> f;

    f(nullptr);

}

One difference between '0' and 'nullptr' is we can’t use the former as the non-type argument of pointer type (see n3090.pdf 14.4.2/5).

template<int *>

struct A {};

void foo()

{

    A<0> b1; // No conversion from 0 to ‘int *’

    A<(int *)0> b2; // OK

    A<nullptr> b3; // OK

}

BTW, VC is not conformant here. It also allows the definition of b1.

Known issues / limitations

After the introduction of nullptr, it is reasonable to change the definition of NULL (The standard says this is implementation defined):

#define NULL nullptr

However, many code bases incorrectly assume NULL to be an integer or '0'. For example:

void f()

{

    char str[] = "a";

    int n = NULL;

    str[0] = NULL;

}

So the change will break lots of existing code L.

Known bugs in VC2010

1. nullptr is allowed as non-type argument for function template

template<int> void f();

void g()

{

    f<nullptr>();

}

2. nullptr is allowed as template template argument

template<template <class> class> class C {};

C<nullptr> c;

3. Some arithmetic operations on nullptr do not generate an error

https://connect.microsoft.com/VisualStudio/feedback/details/505780

void test()

{

    auto x = nullptr;

    x++; // should give error

    x += 1; // should give error

}

We have special handling for nullptr when processing expressions. But apparently some cases are missing.