C++代码用nullptr表达空指针

Last Updated: 2024-01-02 11:09:40 Tuesday

-- TOC --

在C语言中,用得好好的NULL,C++为什么要搞出nullptr呢?

NULL在C中,就是指向0地址void类型的空指针,定义为(void*)0。而在C++中,被定义成了0,但我又觉得它似乎什么都不是,见下文!

在C++中编译下面这行代码会报错,但C代码不会:

// C++
int *p = (void*)0; // error
int *p = reinterpret_cast<int*>((void*)0);  // compile ok, p == nullptr;

报错信息:

error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]

这是C与C++的一个区别:C++不允许将void*隐式地转换成其它类型的指针。(必须使用C++中定义的named-conversion

但C++还是重情义的,必须要考虑兼容C语言这个大兄弟,因此保留了NULL关键字,但重新将其定义为整数0,再增加nullptr类型来表达空指针(从C++11开始)。

因此,现在C++中定义空指针的方式如下:

int *k = NULL;     // OK, but not recommended
int *j = 0;        // the same with above, not recommended
int *h = nullptr;  // BEST

还可以继续用NULL,为什么C++要搞出nullptr这个新的类型?

因为NULL被重新定义为整数0后,存在二义性,它既可以是空指针,也可以是整数,这会带来一些其它的问题。比如,下面是函数重载时出现的二义性:

#include <cstdio>

void abc(void*) {
    printf("void*\n");
}

void abc(int) {
    printf("int\n");
}

int main(void) {
    abc(NULL);
    return 0;
}

上面这段测试代码,在编译的时候,会有如下报错:

error: call of overloaded ‘abc(NULL)’ is ambiguous

如果NULL仅仅是整数0,那么编译器就不会ambiguous,因此NULL在C++中不仅仅是整数0....额...

需要将代码修改为使用nullptr:

abc(nullptr);

结论

在C中用NULL,在C++中只用nullptr表达空指针,如果要使用整数0,也不要用NULL,直接写0最好。

C++之父语录:

Should I use NULL or 0?

In C++ , the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days. If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.

为什么说NULL什么都不是呢?

NULL类型测试C++代码:

#include <iostream>
using namespace std;

int main(){
    cout << is_same<decltype(NULL),decltype(0)>::value << endl;
    cout << is_same<decltype(NULL),decltype((void*)0)>::value << endl;
    cout << is_same<decltype(NULL),decltype(nullptr)>::value << endl;
    return 0;
}

输出3个0!

因此,C++代码不要使用NULL!

本文链接:https://cs.pynote.net/sf/c/cpp/202209161/

-- EOF --

-- MORE --