临时将指针设为 NULL 有什么意义吗?
Is there any point to temporarily making a pointer NULL?
我见过很多这样的代码:
SomeType* ptr = NULL;
ptr = SomeMethod(some, params);
有什么意义?我也看到过它在其他地方声明ptr
(例如在类定义中),然后在类构造函数中会有这个:
ptr = NULL;
ptr = SomeMethod(some, params);
我不明白为什么要这样做。ptr = NULL
线肯定没用吗?
如果"SomeMethod"抛出异常,你的SomeType*将继续指向你不希望它指向的东西。因此,如果您不希望指针再指向旧的东西,将指针设置为 null 绝对是一种很好的做法。
除了抛出异常的非常好点(适用于C++),即使在 C 中也是如此,初始化所有变量也是一个好主意。编译器几乎总是在确定不需要初始化时优化初始化。
这里有一个小例子,说明如果你不这样做会发生什么。
SomeType* ptr;
ptr = SomeMethod(some, params);
如您所见,这工作正常,没有问题ptr
没有有效值。
现在,有人决定添加更多代码是个好主意:
SomeType* ptr;
int x = someotherfunction;
if (x > 90)
{
ptr = SomeMethod(some, params);
}
现在突然间,您的ptr
将有一些随机的废话内容 - 可能是 NULL,但很可能是其他内容。是的,我们都认为我们会记得回来检查一下,看看我们的更改是否影响了其他东西,等等。但是如果你已经编程了几年,我几乎可以肯定你已经遇到过一些"哎呀,没想过"的情况。
想象一下,我添加"someotherfunction"的新代码是 20 或 30 行,您可以清楚地看到问题所在。
在第一种情况下,最好在声明新值时始终分配一个值,这样您就不会最终得到单位化值(一种保护您免受自己的错误)。但是,如果它直接彼此相继,则可以被视为无用。
在第二种情况下,它是完全没用的。
它确实没用(这被称为"死任务")。但是,有些人更喜欢在声明时初始化指向NULL
的指针,然后分别显式分配给它。也许这只是出于可读性的原因(也许有些人认为它更具可读性,或者发现即使例如,赋值被注释掉以进行调试也很有用)。我不确定我会这样做/认为这是实践。
另请注意,因此,大多数编译器会自动优化赋值。
这种做法不仅无用,而且有害。如果你刚刚写:
SomeType* ptr = NULL;
/* lots of stuff in between */
ptr = SomeMethod(some, params);
并且不小心在干预代码中的某处使用了ptr
,编译器将无法通知您此错误。如果你写:
SomeType* ptr;
/* lots of stuff in between */
ptr = SomeMethod(some, params);
那么在赋值之前使用 ptr
就是 UB,一个好的编译器或静态分析工具会通知您此错误。
代码现在毫无用处,但也许使用预测了未来的维护,其中将在冗余初始化和赋值之间添加更多行,以便初始化不再是多余的。
该代码也可能是删除的结果。也就是说,声明和赋值之间可能存在一些代码,但后来被删除了,并且没有进行任何清理以将赋值合并到初始化中。当然,代码是没有意义的;在这种情况下,我们只是有一个关于它是如何变成那样的历史解释(也许还有改变它的理由)。
有时,看似无用的变量初始化是由于有人不得不使编译器警告"可能未使用"变量静音而发生的,如果有多种方法可以访问使用该变量的代码块,并且编译器不够复杂,无法证明在所有情况下变量都以某种方式通过赋值初始化,则可能会发生这种情况。
在声明变量的位置初始化所有变量是一个好习惯,因为它减少了由于未初始化的数据而导致不可预测行为的可能性。一些人认为,当未初始化的变量被初始化所消除时,某些静态工具的效果会降低,这些初始化会给它们不适当的值,从而使错误更难找到。但是,如果错误基于初始化的数据,则它们更具可重复性,并且错误行为很可能也可以在平台之间移植。某些语言会为您初始化本地变量。在Lisp中,(let (x) ...)表示在代码块...
中,变量x
的值为NIL
,因为没有初始值设定项。Lisp 代码的静态分析可以很容易地跟踪事实,例如NIL
被不恰当地传递给数字函数。 在C和相关语言中,问题略有不同,因为对于像int
这样的类型,没有等效的错误类型值,例如NIL
。 因此0
被替换,这是一个有效的值,不会简单地用类型不匹配来破坏计算。不适当的0
可能会导致计算中的算法错误。然而,在指针的情况下,空指针值是NIL
的合理传真,因为它是一个程序员可见的可移植域值,上面写着"我不指向任何对象"。当指针实际上暂时不指向任何东西时,我们应该给它这个值,而不是在其中留下随机位,这可能会意外地指向一个意外的对象。
- C++不重载时间函数,所以我们不需要写 NULL 有什么原因吗?
- 这句C++是什么意思?BaseWindow() : m_hwnd(NULL) { }.
- XOpenDisplay(0) 和 XOpenDisplay(NULL) 有什么区别?
- 在单一实例类中将成员指针设置为 null 的正确方法是什么
- 当使用反向循环逆转字符串时,null字符会发生什么
- const自动参考绑定到(NULL)指针 - 实际类型是什么
- LinkedListInit, LinkedListCreateH 方法中的"L->next=NULL"有什么问题吗?
- 在C++中NULL和__NULL之间有什么区别
- 测试指针是否为null的最有效方法是什么?
- 删除指针并将指针设置为null之间有什么区别
- if(NULL==指针)和if(指针==NULL)之间有什么区别
- 解密字符串末尾的 NULL 终止符需要什么?
- 什么是 C++ std::map 的 null 关键字?
- 从转储中获取调用堆栈的几乎所有帧中的此指针 NULL 表明什么
- 什么是 NULL 的非指针等效项
- C++`int*class::*member=NULL`编译,原因是什么
- *this=NULL在模板类中的方法内部意味着什么
- gdb 错误:找不到方法 (null)什么
- 什么是NULL指针值?
- "- < /dev/null"在"gcc -dM -E - < /dev/null"中是什么意思?