在 C/C++ 中检查空指针

2021-12-12 00:00:00 null c if-statement coding-style c++

在最近的代码审查中,一位贡献者试图强制以下列方式对指针执行所有 NULL 检查:

In a recent code review, a contributor is trying to enforce that all NULL checks on pointers be performed in the following manner:

int * some_ptr;
// ...
if (some_ptr == NULL)
{
    // Handle null-pointer error
}
else
{
    // Proceed
}

代替

int * some_ptr;
// ...
if (some_ptr)
{
    // Proceed
}
else
{
    // Handle null-pointer error
}

我同意他的方式更清楚一点,因为它明确表示确保此指针不为 NULL",但我会反驳说,任何正在处理此代码的人都会理解使用指针if 语句中的变量隐式检查 NULL.另外我觉得第二种方法引入同类错误的可能性较小:

I agree that his way is a little more clear in the sense that it's explicitly saying "Make sure this pointer is not NULL", but I would counter that by saying that anyone who's working on this code would understand that using a pointer variable in an if statement is implicitly checking for NULL. Also I feel the second method has a smaller chance of introducing a bug of the ilk:

if (some_ptr = NULL)

查找和调试绝对是一件痛苦的事情.

which is just an absolute pain to find and debug.

您更喜欢哪种方式,为什么?

Which way do you prefer and why?

推荐答案

根据我的经验,if (ptr)if (!ptr) 形式的测试是首选.它们不依赖于符号 NULL 的定义.他们不会暴露意外分配的机会.它们清晰简洁.

In my experience, tests of the form if (ptr) or if (!ptr) are preferred. They do not depend on the definition of the symbol NULL. They do not expose the opportunity for the accidental assignment. And they are clear and succinct.

正如 SoapBox 在评论中指出的那样,它们与 C++ 类(例如 auto_ptr)兼容,这些类是充当指针的对象并提供到 bool 来启用这个习语.对于这些对象,与 NULL 的显式比较必须调用到指针的转换,这可能具有其他语义副作用,或者比 bool 的简单存在检查更昂贵转换意味着.

As SoapBox points out in a comment, they are compatible with C++ classes such as auto_ptr that are objects that act as pointers and which provide a conversion to bool to enable exactly this idiom. For these objects, an explicit comparison to NULL would have to invoke a conversion to pointer which may have other semantic side effects or be more expensive than the simple existence check that the bool conversion implies.

我更喜欢能说明含义而没有不需要的文本的代码.if (ptr != NULL)if (ptr) 具有相同的含义,但代价是冗余的特异性.下一个合乎逻辑的事情是编写 if ((ptr != NULL) == TRUE) 并且这种方式是疯狂的.C语言很清楚,一个由ifwhile等测试的布尔值具有特定含义,非零值为真,零为假.冗余并没有让它更清楚.

I have a preference for code that says what it means without unneeded text. if (ptr != NULL) has the same meaning as if (ptr) but at the cost of redundant specificity. The next logical thing is to write if ((ptr != NULL) == TRUE) and that way lies madness. The C language is clear that a boolean tested by if, while or the like has a specific meaning of non-zero value is true and zero is false. Redundancy does not make it clearer.

相关文章