你在 C++ 中使用 NULL 还是 0(零)作为指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/176989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:26:52  来源:igfitidea点击:

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

c++null

提问by camh

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.

在 C++ 的早期,当它被栓在 C 之上时,您不能使用 NULL,因为它被定义为(void*)0. 您不能将 NULL 分配给除 之外的任何指针void*,这使它变得毫无用处。在那些日子里,人们接受您使用0(零)作为空指针。

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:

直到今天,我还在继续使用零作为空指针,但我周围的人坚持使用NULL. 我个人认为给NULL现有值命名 ( )没有任何好处- 而且因为我也喜欢将指针测试为真值:

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 NULLis zero, in which case why use NULL).

那么使用零更有意义(就像如果你使用NULL,你不能在逻辑上使用p && !q- 你需要明确地与 比较NULL,除非你假设NULL为零,在这种情况下为什么使用NULL)。

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

是否有任何客观原因更喜欢零而不是 NULL(反之亦然),或者只是个人喜好?

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.

编辑:我应该补充(并且原本打算说)对于 RAII 和异常,我很少使用零/空指针,但有时您仍然需要它们。

采纳答案by Martin Cote

Here's Stroustrup's take on this: C++ Style and Technique FAQ

这是 Stroustrup 对此的看法:C++ 风格和技术常见问题解答

In C++, the definition of NULLis 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULLis that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULLwas/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, nullptrwill be a keyword.

在 C++ 中, 的定义NULL是 0,所以只有审美差异。我更喜欢避免使用宏,所以我使用 0。另一个问题NULL是人们有时会错误地认为它不同于 0 和/或不是整数。在标准前的代码中,NULL有时被/被定义为不合适的东西,因此必须/必须避免。这几天不太常见。

如果您必须命名空指针,请调用它nullptr;这就是它在 C++11 中的名称。然后,nullptr将是一个关键字。

That said, don't sweat the small stuff.

也就是说,不要为小事出汗。

回答by Richard Corden

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

我认为有一些论点(其中一个是相对较新的)与 Bjarne 对此的立场相矛盾。

  1. Documentation of intent
  1. 意向文件

Using NULLallows for searches on it's use and it also highlights that the developer wantedto use a NULLpointer, irrespective of whether it is being interpreted by the compiler as NULLor not.

UsingNULL允许对其使用进行搜索,它还强调了开发人员想要使用NULL指针,而不管编译器是否将其解释为NULL

  1. Overload of pointer and 'int' is relatively rare
  1. 指针和 'int' 的重载相对少见

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 inttoo, as any other type will result in an ambiguous call and so generate a helpful compiler warning.

然而,至少在我看来,上面的问题不在于我们对空指针常量使用 NULL,而是我们有 'foo' 的重载,它采用非常不同的参数。参数必须是 an inttoo,因为任何其他类型都会导致模棱两可的调用,因此会生成有用的编译器警告。

  1. Analysis tools can help TODAY!
  1. 分析工具今天可以提供帮助!

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

即使在没有 C++ 0x 的情况下,今天也有可用的工具来验证它NULL用于指针,以及0用于整数类型。

  1. C++ 11will have a new std::nullptr_ttype.
  1. C++ 11将有一个新std::nullptr_t类型。

This is the newest argument to the table. The problem of 0and NULLis 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:

这是该表的最新参数。C++ 0x 正在积极解决0和的问题NULL,您可以保证对于提供 的每个实现NULL,他们将做的第一件事是:

#define NULL  nullptr

For those who use NULLrather 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 NULLfor 0. For anybody using 0today....erm...well hopefully they have a good knowledge of regular expressions...

对于那些谁使用NULL,而不是0,这种变化将在很少或根本没有力气类型安全性的提高-如果有的话,还可以赶上他们已经使用了一些错误NULL0。对于0今天使用的任何人......呃......希望他们对正则表达式有很好的了解......

回答by Andy Lester

Use NULL. NULL shows your intent. That it is 0 is an implementation detail that should not matter.

使用 NULL。NULL 显示您的意图。它是 0 是一个无关紧要的实现细节。

回答by Andrew Stein

I always use:

我总是使用:

  • NULLfor pointers
  • '\0'for chars
  • 0.0for floats and doubles
  • NULL指针
  • '\0'对于字符
  • 0.0花车和双打

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

其中 0 会很好。这是一个信号意图的问题。也就是说,我不是肛门的。

回答by Ferruccio

I stopped using NULL in favor of 0 long ago (as well as as most other macros). I did this not only because I wanted to avoid macros as much as possible, but also because NULL seems to have become over-used in C and C++ code. It seems to be used whenever a 0 value is needed, not just for pointers.

我很久以前就停止使用 NULL 来支持 0(以及大多数其他宏)。我这样做不仅是因为我想尽可能地避免使用宏,还因为 NULL 似乎在 C 和 C++ 代码中被过度使用了。它似乎在需要 0 值时使用,而不仅仅是用于指针。

On new projects, I put this in a project header:

在新项目中,我将其放在项目标题中:

static const int nullptr = 0;

Now, when C++0x compliant compilers arrive, all I have to do is remove that line. A nice benefit of this is that Visual Studio already recognizes nullptr as a keyword and highlights it appropriately.

现在,当符合 C++0x 的编译器到来时,我所要做的就是删除该行。这样做的一个好处是 Visual Studio 已经将 nullptr 识别为关键字并适当地突出显示它。

回答by abonet

    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

The moral of the story. You should use NULL when you're dealing with pointers.

这个故事的主旨。在处理指针时应该使用 NULL。

1) It declares your intent (don't make me search through all your code trying to figure out if a variable is a pointer or some numeric type).

1)它声明了你的意图(不要让我搜索你所有的代码,试图找出一个变量是指针还是某种数字类型)。

2) In certain API calls that expect variable arguments, they'll use a NULL-pointer to indicate the end of the argument list. In this case, using a '0' instead of NULL can cause problems. On a 64-bit platform, the va_arg call wants a 64-bit pointer, yet you'll be passing only a 32-bit integer. Seems to me like you're relying on the other 32-bits to be zeroed out for you? I've seen certain compilers (e.g. Intel's icpc) that aren't so gracious -- and this has resulted in runtime errors.

2) 在某些需要可变参数的 API 调用中,它们将使用 NULL 指针来指示参数列表的结尾。在这种情况下,使用“0”而不是 NULL 会导致问题。在 64 位平台上, va_arg 调用需要一个 64 位指针,但您将只传递一个 32 位整数。在我看来,您似乎依赖其他 32 位为您清零?我见过某些不太友好的编译器(例如 Intel 的 icpc)——这导致了运行时错误。

回答by Daemin

If I recall correctly NULL is defined differently in the headers that I have used. For C it is defined as (void*)0, and for C++ it's defines as just 0. The code looked something like:

如果我没记错的话,NULL 在我使用的标头中的定义不同。对于 C,它被定义为 (void*)0,而对于 C++,它被定义为 0。代码看起来像:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

Personally I still use the NULL value to represent null pointers, it makes it explicit that you're using a pointer rather than some integral type. Yes internally the NULL value is still 0 but it isn't represented as such.

就我个人而言,我仍然使用 NULL 值来表示空指针,它明确表示您使用的是指针而不是某种整数类型。是的,内部 NULL 值仍然是 0,但它没有这样表示。

Additionally I don't rely on the automatic conversion of integers to boolean values but explicitly compare them.

此外,我不依赖于整数到布尔值的自动转换,而是明确地比较它们。

For example prefer to use:

例如更喜欢使用:

if (pointer_value != NULL || integer_value == 0)

rather than:

而不是:

if (pointer_value || !integer_value)


Suffice to say that this is all remedied in C++11 where one can simply use nullptrinstead of NULL, and also nullptr_tthat is the type of a nullptr.

可以说,这在 C++11 中都得到了补救,其中可以简单地使用nullptr代替NULL,而且nullptr_t这也是 a 的类型nullptr

回答by Gaute Lindkvist

I would say history has spoken and those who argued in favour of using 0 (zero) were wrong (including Bjarne Stroustrup). The arguments in favour of 0 were mostly aesthetics and "personal preference".

我会说历史已经说过,那些赞成使用 0(零)的人是错误的(包括 Bjarne Stroustrup)。赞成 0 的论据主要是美学和“个人偏好”。

After the creation of C++11, with its new nullptr type, some compilers have started complaining (with default parameters) about passing 0 to functions with pointer arguments, because 0 is not a pointer.

在创建 C++11 之后,使用新的 nullptr 类型,一些编译器开始抱怨(使用默认参数)将 0 传递给带有指针参数的函数,因为 0 不是指针。

If the code had been written using NULL, a simple search and replace could have been performed through the codebase to make it nullptr instead. If you are stuck with code written using the choice of 0 as a pointer it is far more tedious to update it.

如果代码是使用 NULL 编写的,则可以通过代码库执行简单的搜索和替换,使其变为 nullptr。如果您坚持使用选择 0 作为指针编写的代码,那么更新它会更加乏味。

And if you have to write new code right now to the C++03 standard (and can't use nullptr), you really should just use NULL. It'll make it much easier for you to update in the future.

如果您现在必须按照 C++03 标准编写新代码(并且不能使用 nullptr),那么您真的应该只使用 NULL。这将使您将来更容易更新。

回答by mxg

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

我曾经在一台机器上工作过,其中 0 是一个有效地址,而 NULL 被定义为一个特殊的八进制值。在那台机器上(0 != NULL),所以代码如

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.

虽然我相信现在大多数编译器都将 NULL 定义为 0,但我仍然记得多年前的教训:NULL 不一定是 0。

回答by jon-hanson

I usually use 0. I don't like macros, and there's no guarantee that some third party header you're using doesn't redefine NULL to be something odd.

我通常使用 0。我不喜欢宏,并且不能保证您使用的某些第三方标头不会将 NULL 重新定义为奇怪的东西。

You could use a nullptr object as proposed by Scott Meyers and others until C++ gets a nullptr keyword:

您可以使用 Scott Meyers 和其他人提出的 nullptr 对象,直到 C++ 获得 nullptr 关键字:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

Google "nullptr" for more info.

谷歌“nullptr”了解更多信息。