使用重载删除删除对象之前进行 NULL 检查
这是代码审查评论之一。
在调用任何对象的删除之前检查 NULL 是个好主意吗?
我确实理解删除运算符在内部检查 NULL 并且是多余的,但提出的论点是删除,因为运算符可以重载,如果重载版本不检查 NULL 它可能会崩溃。那么,假设如果以及何时删除将被重载,它会检查 NULL 是否安全合理? 根据我的理解,假设第一种情况是合理的,即重载删除应负责 NULL 检查,并且审查点并不成立。你怎么认为?
This came up as one of the code review comments.
Is it a good idea to check for NULL before calling delete for any object?
I do understand delete operator checks for NULL internally and is redundant but the argument put forth was delete as an operator can be overloaded and if the overloaded version doesn't check for the NULL it may crash. So is it safe and reasonable to assume that if and when delete will be overloaded it will check for the NULL or not?
In my understanding its reasonable to assume the first case that overloaded delete shall take care of the NULL check, and the review point doesn't hold good. What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
不,不要检查 null。标准规定
delete (T*)0;
是有效的。它只会使你的代码变得复杂而没有任何好处。如果operator delete
重载,最好在操作符的实现中检查 null 。只是保存代码行和错误。编辑:这个答案被接受并投票,但在我看来,它的信息量不是很大。这里的所有答案都缺少一个部分,为了良心,让我在这里添加最后一个部分。
该标准实际上在 [basic.stc.dynamic] 中说,至少从 C++03 开始:
引用的部分以及其他答案中列出的标准中的其他一些地方都说传递空指针的语义是无操作。
No, don't check for null. The standard says that
delete (T*)0;
is valid. It will just complicate your code for no benefits. Ifoperator delete
is overloaded it's better to check for null in the implementation of the operator. Just saves code lines and bugs.EDIT: This answer was accepted and upvoted, yet, in my opinion, it was not very informative. There is one missing piece in all answers here, and, for conscience sake, let me add this last piece here.
The standard actually says in [basic.stc.dynamic], at least since C++03:
Where the referenced sections, as well as some other places in the standard listed in other answers, say that the semantics of passing a null pointer are a no-op.
我想说,这更多是确保如果您重载
operator delete
,那么您应该始终让它检查NULL
,否则您就会破坏语义。I would say that that's more a reason to ensure that if you overload
operator delete
, then you should always have it check forNULL
, otherwise you're breaking the semantics.不!
标准规定[第 5.3.5/2 节]
此外,在
18.4.1.1/13
节中voidoperatordelete(void*ptr) throw();
voidoperatordelete(void*ptr, const std::nothrow_t& ;) 抛出();
编辑:
James Kanze 此处 说的是
No!
The Standard says [Section 5.3.5/2]
Furthermore in Section
18.4.1.1/13
void operator delete(void* ptr) throw();
void operator delete(void* ptr, const std::nothrow_t&) throw();
EDIT :
James Kanze here says that
我想说,重载的
delete
有责任像您期望的delete
那样行事。也就是说,它应该将NULL指针作为无操作来处理。因此,当调用重载删除时,您不应该检查 NULL。您应该依靠重载删除来正确实现。
I would say it is the responsibility of an overloaded
delete
to behave like you expectdelete
to behave. That is, it should handle NULL pointers as a no-op.And so, when calling an overloaded delete, you should not check for NULL. You should rely on the overloaded delete to be implemented correctly.
无需检查 null。删除运算符会检查 null,因此不需要额外的检查。
No need to check null. delete operator does chck for null so additional check is not required.
delete (T*)0;
有效且不执行任何操作,同样free(NULL);
也是有效且不执行任何操作。如果重载delete
运算符,您的实现应该具有相同的语义。该标准说明了标准delete
将如何工作,但我不认为它说明了重载的delete
应该如何表现。为了与标准/默认行为保持一致,它应该允许(T*)0
作为输入。delete (T*)0;
is valid and does nothing, similarlyfree(NULL);
is also valid and does nothing. If you overload thedelete
operator, your implementation should carry the same semantics. The standard says how the standarddelete
will work, but I don't think it says how an overloadeddelete
should behave. For the sake of consistency with the standard/default behaviour, it should allow(T*)0
as input.来自标准文档,18.5.1.1.13 下的
delete
,因此,您不必默认检查..
From Standard docs, 18.5.1.1.13 under
delete
,So, you don't have to check by default..
删除之前无需检查 NULL。如果有人使用不按标准方式运行的内容来重载
delete
,那么这就是真正的问题。任何人都不应轻视重载delete
的任务,并且应始终支持预期的行为,例如检查 NULL 和不采取任何操作。但是,无论如何,您应该始终记住为刚刚删除的任何指针分配零,除非您也打算删除该指针:
No need to check for NULL prior to deleting. If someone has overloading
delete
with something that does not behave in a standard way then that's the real problem. No-one should take lightly the task of overloadingdelete
and should always support expected behaviour such as checking for NULL and taking no action.However, for what it's worth, you should always remember to assign zero to any pointer that you've just deleted, unless for example you are about to delete the pointer as well:
是否不需要需要检查。如果任何人超载了该方法,他就有责任对 NULL 进行处理。
Is it not necesary to check. If anyone overload the pethod, is his responsibility to to whatever with NULL.
我想说这些问题包含不完整的信息。我的商店在我们的编码标准中仍然在删除之前检查 NULL,因为我们仍然有一个必须支持的编译器/平台配置,如果传递 NULL,它就会进入默认删除运算符的未定义行为。如果原发帖者有类似的情况,那么就需要检查 NULL,否则,请更改编码标准!
I would say the questions contains incomplete information. My shop still has a check for NULL before delete in our coding standard, as we still have one compiler/platform configuration that we must support that goes into undefined behavior with the defualt delete operator if it is passed NULL. If the original poster has a simular situation then there is a point to the check for NULL, otherwise, change the coding standard!
一点 C++ 的迂腐:
NULL 不是一个内置的概念。是的,我们都知道这意味着什么,但在 C++0X 之前的 C++ 中,空指针概念只是值 0。NULL 通常是扩展为 0 的特定于平台的宏。
在 C++0X 中,我们得到 nullptr,它是比普通的零更清晰,并且不能转换为除 bool 之外的任何整数类型,并且是比 NULL 更好的概念(或者可能是 NULL 背后概念的更好实现)。
A bit of C++ pedantry:
NULL is not a built-in concept. Yes we all know what it means but in C++ before C++0X the null pointer concept is simply the value 0. NULL is usually a platform-specific macro that expands to 0.
With C++0X we're getting nullptr which is clearer than a plain zero and is not convertible to any integral type except bool, and is a better concept than NULL (or perhaps a better implementation of the concept behind NULL).