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

2019-05-08 16:59发布

在C初期++,当它被闩上的C顶部,因为它被定义为你不能使用NULL (void*)0 。 你不能指定NULL之外的任何指针void* ,这使得它那种无用的。 早在那些日子里,它被接受,你用0空指针(零)。

为了这一天,我继续使用零作为空指针,但我身边的人坚持使用NULL 。 我个人看不出有什么好处给名字( NULL到现有的值) -因为我也想考验指针作为真值:

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

然后使用零更有意义(如如果使用NULL ,则不能使用逻辑p && !q -你需要明确对比较NULL ,除非你认为NULL是零,在这种情况下,为什么还要用NULL )。

是否有任何客观理由,更喜欢在零NULL(反之亦然),或者一切只是个人喜好?

编辑:我要补充(并意味着原来说的),与RAII和例外,我很少用零/ NULL指针,但有时候你仍然需要它们。

Answer 1:

这里是Stroustrup的拿到这个: C ++风格与技术FAQ

在C ++中,定义NULL为0,所以只有一个审美差。 我倾向于避免宏,所以我用0与另一个问题NULL是,人们有时会误认为它是由0和/或不为整数不同。 在预标准码, NULL物/有时被定义的东西不适合的,因此不得不/必须避免。 这是不常见的,这些天。

如果您有命名空指针,把它nullptr ; 这就是它被称为在C ++ 11。 然后, nullptr将是一个关键词。

这就是说,不出汗的小东西。



Answer 2:

有几个参数(其中一个是相对较新的),我相信矛盾比亚的这一立场。

  1. 意图的文档

使用NULL允许它的使用搜索,同时也强调了开发者用一个NULL指针,不论它是由编译器所解释NULL与否。

  1. 指针和“廉政”的过载是比较少见的

大家引用的例子是:

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

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

然而,至少在我看来,上述问题不在于我们使用NULL为空指针常量,那就是我们有“富”,这需要很大的不同类型的参数的重载。 该参数必须是一个int也一样,任何其他类型将导致暧昧通话等产生有益的编译器警告。

  1. 分析工具可以帮助今天!

即使没有的C ++ 0x的,也有当今的工具,确认NULL被用于指针,而0被用于整数类型。

  1. C ++ 11将有一个新std::nullptr_t类型。

这是最新的参数表。 的问题0NULL正在积极处理对于C ++ 0x中,你可以保证每个提供执行NULL ,第一件事,他们需要做的是:

#define NULL  nullptr

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



Answer 3:

使用NULL。 NULL显示你的意图。 它是0是一个实现细节是不应该的问题。



Answer 4:

我总是用:

  • NULL的指针
  • '\0'为字符
  • 0.0对浮点型和双

其中0会做的罚款。 这是信令意图的问题。 这就是说,我不是肛门它。



Answer 5:

我停下赞成0不久前使用NULL(以及大多数其他宏)。 我这样做,不仅是因为我想避免的宏尽可能,也因为空似乎已经成为了C和C ++代码过度使用。 似乎每当需要一个0值,不只是为指针使用。

在新的项目,我把这个项目中的标头:

static const int nullptr = 0;

现在,当的C ++ 0x标准的编译器到达,所有我需要做的就是删除了这一行。 这方面的一个很好的好处是,Visual Studio中已经承认nullptr作为关键字,并适当突出了它。



Answer 6:

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

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

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

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

2)在期望可变参数的某些API调用,他们将使用一个NULL指针来指示参数列表的末尾。 在这种情况下,使用“0”,而不是NULL的可能会导致问题。 在64位平台上,在va_arg调用想要一个64位指针,但你会路过只有32位整数。 在我看来,像你依靠其他32位,以供您将被归零了呢? 我见过某些编译器(如英特尔的ICPC)是不那么亲切 - 这已导致运行错误。



Answer 7:

如果我没有记错NULL是我所使用的头有不同的定义。 对于C它被定义为(无效*)0,并为C ++它作为定义只是0的代码看上去是这样的:

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

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

此外,我不依赖于整数布尔值的自动转换,但明确地对它们进行比较。

例如喜欢使用:

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

而不是:

if (pointer_value || !integer_value)

我只想说,这是所有补救在C ++ 11,其中一个可以简单地使用nullptr而非NULL ,也nullptr_t这是一个类型nullptr



Answer 8:

我会说,历史已经口头和那些谁赞成使用0(零)的主张是错误的(包括了Bjarne Stroustrup的)。 赞成0的参数大多是美学和“个人喜好”。

创建C ++ 11后,其新nullptr类型,一些编译器已经开始有关将0到功能与指针参数抱怨(使用默认参数),因为0不是一个指针。

如果代码已经被使用NULL写的,一个简单的搜索和替换原本可以通过已经基本代码执行,使其nullptr来代替。 如果你被卡住使用0选择作为指针编写的代码是更繁琐的更新。

如果你现在所拥有的编写新的代码到C ++ 03标准(而不能使用nullptr),你真的应该只使用NULL。 这将使它更容易为你在未来的更新。



Answer 9:

我通常用0我不喜欢宏,而且也不能保证你使用的是不重新定义NULL一些第三方的头是一个奇怪的现象。

如提出斯科特迈尔斯和其他人,你可以使用一个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 = {};

谷歌“nullptr”获取更多信息。



Answer 10:

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

char *p;

...

if (p) { ... }

像您期望的是行不通的。 你必须写

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

虽然我相信大多数编译器定义NULL为0,这些天我还记得那些多年前的教训:NULL不一定是0。



Answer 11:

我认为标准保证NULL == 0,所以你可以做任何。 我喜欢NULL,因为它记录了你的意图。



Answer 12:

使用0或NULL将有同样的效果。

然而,这并不意味着他们都是良好的编程习惯。 由于在性能上没有差异,在选择一个不可知论者/抽象替代低级别感知的选择是一个不好的编程习惯。 帮助你的代码的读者了解你的思维过程

NULL,0,0.0,“\ 0”,0x00,并whatelse全部转化为同样的事情,但在你的程序不同的逻辑实体。 他们应该这样使用。 NULL是一个指针,0是数量,为0x0是一个值,其位是有趣等你不会分配“\ 0”的指针是否其编译或没有。

我知道一些社区鼓励破坏环境的合同证明了深入的环境的知识。 负责任的程序员,但是,使维护的代码,并保持这种做法超出他们的代码。



Answer 13:

奇怪,没有人,包括Stroustroup提到。 虽然谈论了很多的标准和美学没有人注意到它是危险的使用0NULL的代替的架构,例如,在可变参数列表,其中sizeof(int) != sizeof(void*) 。 像Stroustroup,我更喜欢0审美的原因,但是你要小心,不要使用它在那里它的类型可能是不明确的。



Answer 14:

我尝试尽可能地使用C ++的引用避免了整个问题。 而不是

void foo(const Bar* pBar) { ... }

你可能经常能够写

void foo(const Bar& bar) { ... }

当然,这并不总是有效; 但空指针可以被过度使用。



Answer 15:

我与斯特劳斯我就这一个:-)因为NULL不是语言的一部分,我更喜欢使用0。



Answer 16:

大多是个人喜好,但一个能有这样的NULL使得它相当明显的论点,对象是一个指针,它目前没有指向任何东西,如

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC,该标准不要求空为0,所以使用任何定义在<STDDEF.H>可能是最适合你的编译器。

另一个方面的说法是,你是否应该使用逻辑比较(隐式转换为布尔)或明确地对证NULL,但归结为可读性为好。



Answer 17:

我更喜欢,因为它清楚地表明你的意图是该值表示的指针不是一个算术值使用NULL。 这是一个宏观的事实是不幸的,但因为它是如此广泛根深蒂固几乎没有危险(除非有人做一些真正愚蠢的)。 我不希望它是从一开始的关键词,但你能做什么?

这就是说,我必须使用指针作为真值本身没有问题。 正如NULL,这是一个根深蒂固的习惯用法。

C ++ 09将增加的nullptr结构,我认为是姗姗来迟。



Answer 18:

我总是用0不为任何真正想出来的原因,只是因为当我第一次学习C ++我读使用0所推荐的东西,我只是一直在做这种方式。 在理论上有可能在可读性混乱的问题,但在实践中我从来没有曾经碰到过这样的问题在数千工时和数百万行的代码。 由于斯特劳斯说,这真的只是一个个人的审美问题,直到标准变为nullptr。



Answer 19:

有人曾经告诉我......我要重新定义NULL到69从那以后我不使用它:P

它使你的代码非常脆弱。

编辑:

在标准并非一切都是完美的。 宏NULL是一个实现定义的C ++空指针常量不使用C NULL宏完全兼容,除了什么类型隐藏隐含它在一个无用的和容易出错的工具转换。

NULL并不表现为一个空指针,但作为一个O / OL文字。

告诉我下一个例子是不混乱:

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

正因为这一切,在新的标准出现的std :: nullptr_t

如果你不想等待新的标准,要使用nullptr,使用至少一个体面的一个像由迈尔斯建议(见jon.h评论)。



Answer 20:

那么我认为不使用0或NULL指针在所有只要有可能。

使用它们迟早会导致你的代码段故障。 在我的经验,并在gereral指针在C错误的最大来源之一++

同时,它会导致“如果 - 不空”的语句都在你的代码。 更漂亮,如果你可以依靠总是有效状态。

几乎总有一个更好的选择。



Answer 21:

指针设置为0就是不说清楚。 特别是如果你来比C ++以外的语言。 这包括C作为以及如JavaScript。

最近,我与衣食住行,像这样一些代码:

virtual void DrawTo(BITMAP *buffer) =0;

对于首次纯虚函数。 我认为这是一些神奇的jiberjash了一个星期。 当我意识到这是函数指针基本上只是设置为null (虚拟函数只是函数指针在大多数情况下,C ++)我踢自己。

virtual void DrawTo(BITMAP *buffer) =null;

本来比没有适当的间距是basterdation到我的新的眼睛不易混淆。 其实,我很奇怪,为什么C ++不使用小写null很像现在全球员工总数小写虚实。



文章来源: Do you use NULL or 0 (zero) for pointers in C++?
标签: c++ null