Do you use NULL or 0 (zero) for pointers in C++?

2019-01-01 06:08发布

In the early days of C++ when it was bolted on top of C, you could not use NULL as it was defined as (void*)0. You could not assign NULL to any pointer other than void*, which made it kind of useless. Back in those days, it was accepted that you used 0 (zero) for null pointers.

To this day, I have continued to use zero as a null pointer but those around me insist on using NULL. I personally do not see any benefit to giving a name (NULL) to an existing value - and since I also like to test pointers as truth values:

if (p && !q)
  do_something();

then using zero makes more sense (as in if you use NULL, you cannot logically use p && !q - you need to explicitly compare against NULL, unless you assume NULL is zero, in which case why use NULL).

Is there any objective reason to prefer zero over NULL (or vice versa), or is all just personal preference?

Edit: I should add (and meant to originally say) that with RAII and exceptions, I rarely use zero/NULL pointers, but sometimes you do need them still.

标签: c++ null
22条回答
谁念西风独自凉
2楼-- · 2019-01-01 06:57

There are a few arguments (one of which is relatively recent) which I believe contradict Bjarne's position on this.

  1. Documentation of intent

Using NULL allows for searches on it's use and it also highlights that the developer wanted to use a NULL pointer, irrespective of whether it is being interpreted by the compiler as NULL or not.

  1. Overload of pointer and 'int' is relatively rare

The example that everybody quotes is:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

However, at least in my opinion, the problem with the above is not that we're using NULL for the null pointer constant, it's that we have overloads of 'foo' which take very different kinds of arguments. The parameter must be an int too, as any other type will result in an ambiguous call and so generate a helpful compiler warning.

  1. Analysis tools can help TODAY!

Even in the absence of C++ 0x, there are tools available today that verify that NULL is being used for pointers, and that 0 is being used for integral types.

  1. C++ 11 will have a new std::nullptr_t type.

This is the newest argument to the table. The problem of 0 and NULL is being actively addressed for C++ 0x, and you can guarantee that for every implementation that provides NULL, the very first thing that they will do is:

#define NULL  nullptr

For those who use NULL rather than 0, the change will be an improvement in type-safety with little or no effort - if anything it may also catch a few bugs where they've used NULL for 0. For anybody using 0 today....erm...well hopefully they have a good knowledge of regular expressions...

查看更多
呛了眼睛熬了心
3楼-- · 2019-01-01 06:57

Based on my knowledge it is good for prefer nullptr because 0 is int and NULL is 0L (long type), if you have three different overload function

void foo(int);
void foo(bool);
void foo(void*); 

then calling foo(0) call the int one not the pointer and calling foo(NULL) maybe ambiguous for compiler because a long type can convert to int and bool and pointer without any problem so how compiler know which function you are calling.

this is an example of situation that you need to consider that don't use 0 and NULL as nullptr but if you use 0 and NULL in context that compiler can interpret as pointer it will do that .

查看更多
梦寄多情
4楼-- · 2019-01-01 06:58

I once worked on a machine where 0 was a valid address and NULL was defined as a special octal value. On that machine (0 != NULL), so code such as

char *p;

...

if (p) { ... }

would not work as you expect. You HAD to write

if (p != NULL) { ... }

Although I believe most compilers define NULL as 0 these days I still remember the lesson from those years ago: NULL is not necessarily 0.

查看更多
步步皆殇っ
5楼-- · 2019-01-01 06:58

Someone told me once... I am going to redefine NULL to 69. Since then I don't use it :P

It makes your code quite vulnerable.

Edit:

Not everything in the standard is perfect. The macro NULL is an implementation-defined C++ null pointer constant not fully compatible with C NULL macro, what besides the type hiding implicit convert it in a useless and prone to errors tool.

NULL does not behaves as a null pointer but as a O/OL literal.

Tell me next example is not confusing:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

Is because of all that, in the new standard appears std::nullptr_t

If you don't want to wait for the new standard and want to use a nullptr, use at least a decent one like the proposed by Meyers (see jon.h comment).

查看更多
步步皆殇っ
6楼-- · 2019-01-01 07:00

I always use:

  • NULL for pointers
  • '\0' for chars
  • 0.0 for floats and doubles

where 0 would do fine. It is a matter of signaling intent. That said, I am not anal about it.

查看更多
十年一品温如言
7楼-- · 2019-01-01 07:00

Strange, nobody, including Stroustroup mentioned that. While talking a lot about standards and aesthetics nobody noticed that it is dangerous to use 0 in NULL's stead, for instance, in variable argument list on the architecture where sizeof(int) != sizeof(void*). Like Stroustroup, I prefer 0 for aesthetic reasons, but one has to be careful not to use it where its type might be ambiguous.

查看更多
登录 后发表回答