在C++的早期,当它被用螺栓固定在C之上时,你不能使用NULL,因为它被定义为(void*)0
.你不能将NULL分配给除了之外的任何指针void*
,这使得它变得毫无用处.在那些日子里,人们接受了你使用0
(零)空指针.
直到今天,我继续使用零作为空指针,但我周围的人坚持使用NULL
.我个人认为给NULL
现有值一个name()没有任何好处- 因为我也喜欢将指针测试为真值:
if (p && !q) do_something();
然后使用零更有意义(如果你使用NULL
,你不能逻辑使用p && !q
- 你需要明确比较NULL
,除非你假设NULL
是零,在这种情况下为什么使用NULL
).
有没有客观的理由偏好零而不是NULL(反之亦然),或者只是个人偏好?
编辑:我应该添加(并且最初要说)使用RAII和异常,我很少使用零/ NULL指针,但有时你确实需要它们.
这是Stroustrup对此的看法:C++ Style and Technique FAQ
在C++中,定义
NULL
为0,因此只有美学差异.我更喜欢避免宏,所以我使用0.另一个问题NULL
是人们有时会错误地认为它与0和/或不是整数不同.在预标准代码中,NULL
/有时被定义为不适合的东西,因此必须/必须避免.这些日子不太常见.如果必须命名空指针,请调用它
nullptr
; 这就是它在C++ 11中所称的内容.然后,nullptr
将是一个关键字.
也就是说,不要让小东西流汗.
有一些论点(其中一个是相对较新的),我认为这与Bjarne的立场相矛盾.
意图文件
使用NULL
允许搜索它的使用,它还强调开发人员想要使用NULL
指针,无论编译器是否正在解释它NULL
.
指针和'int'的重载相对较少
每个人引用的例子是:
void foo(int*); void foo (int); void bar() { foo (NULL); // Calls 'foo(int)' }
但是,至少在我看来,上面的问题并不是我们对空指针常量使用NULL,而是我们有'foo'的重载,这些重载采用了不同类型的参数.该参数也必须是一个int
,因为任何其他类型都会导致模糊调用,因此生成一个有用的编译器警告.
分析工具可以帮助今天!
即使在没有C++ 0x的情况下,现在还有一些工具可用于验证NULL
用于指针的工具,以及0
用于整数类型的工具.
C++ 11将有一个新std::nullptr_t
类型.
这是该表的最新参数.C++ 0x 的问题0
和NULL
正在积极解决,你可以保证,对于提供的每个实现NULL
,他们将要做的第一件事是:
#define NULL nullptr
对于那些谁使用NULL
,而不是0
,这种变化将在很少或根本没有力气类型安全性的提高-如果有的话,还可以赶上他们已经使用了一些错误NULL
的0
.对于0
今天使用的任何人......呃......希望他们对正则表达有很好的了解......
使用NULL.NULL显示您的意图.它是0是一个无关紧要的实现细节.
我一直用:
NULL
指针
'\0'
为了chars
0.0
用于浮动和双打
其中0会很好.这是信号意图的问题.那就是说,我不是肛门.
我很久以前就停止使用NULL(和大多数其他宏一样).我这样做不仅是因为我想尽可能地避免使用宏,而且因为NULL似乎已经在C和C++代码中被过度使用了.它似乎只在需要0值时使用,而不仅仅是指针.
在新项目中,我将其放在项目标题中:
static const int nullptr = 0;
现在,当符合C++ 0x的编译器到达时,我所要做的就是删除该行.这样做的一个很好的好处是Visual Studio已经将nullptr识别为关键字并适当地突出显示它.
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位为你清零一样?我已经看到某些编译器(例如Intel的icpc)并不那么优雅 - 这导致了运行时错误.
如果我没记错的话,在我使用的标题中定义了NULL.对于C,它定义为(void*)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
就是a的类型nullptr
.
我会说历史已经说过,那些赞成使用0(零)的人是错的(包括Bjarne Stroustrup).支持0的论据主要是美学和"个人偏好".
在使用新的nullptr类型创建C++ 11之后,一些编译器开始抱怨(使用默认参数)将0传递给具有指针参数的函数,因为0不是指针.
如果代码是使用NULL编写的,则可以通过代码库执行简单的搜索和替换,以使其成为nullptr.如果您遇到使用0选择作为指针编写的代码,则更新它会更加繁琐.
如果你现在必须编写新的代码到C++ 03标准(并且不能使用nullptr),你真的应该使用NULL.这将使您将来更新更容易.
我曾经在一台机器上工作,其中0是有效地址,NULL被定义为一个特殊的八进制值.在那台机器上(0!= NULL),所以代码如
char *p; ... if (p) { ... }
不会像你期望的那样工作.你必须写
if (p != NULL) { ... }
虽然我相信大多数编译器现在将NULL定义为0,但我仍记得那些年前的教训:NULL不一定是0.
我通常使用0.我不喜欢宏,并且不能保证您使用的某些第三方标头不会将NULL重新定义为奇怪的东西.
您可以使用Scott Meyers和其他人提出的nullptr对象,直到C++获得nullptr关键字:
const // It is a const object... class nullptr_t { public: templateoperator T*() const // convertible to any type of null non-member pointer... { return 0; } template 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"了解更多信息.
我认为标准保证NULL == 0,所以你可以做到.我更喜欢NULL,因为它记录了你的意图.
使用0或NULL将具有相同的效果.
但是,这并不意味着它们都是良好的编程实践.鉴于性能没有差异,在不可知/抽象替代方案上选择低级别感知选项是一种糟糕的编程习惯.帮助您的代码读者理解您的思考过程.
NULL,0,0.0,'\ 0',0x00和whatelse都转换为相同的东西,但是程序中的逻辑实体不同.它们应该这样使用.NULL是一个指针,0是数量,0x0是一个有趣的位等等.无论是否编译,都不会将"\ 0"分配给指针.
我知道一些社区鼓励通过违反环境合同来展示对环境的深入了解.但是,负责任的程序员可以编写可维护的代码,并将这些实践保留在代码之外.
奇怪,没有人,包括Stroustroup提到的那个.虽然谈论了很多的标准和美学没有人注意到它是危险的使用0
中NULL
的代替,例如,在变量参数列表上的架构,其中sizeof(int) != sizeof(void*)
.像Stroustroup一样,我更喜欢0
美学原因,但是必须小心不要在类型可能不明确的地方使用它.