我更喜欢代码能够表达其含义,而无需不必要的文本。 if (ptr != NULL) 与 if (ptr) 具有相同的含义,但代价是冗余的特异性。下一个合乎逻辑的事情是编写 if ((ptr != NULL) == TRUE) ,这样就很疯狂。 C语言明确通过if、while等测试的布尔值有特定的含义,非零值为真,零为假。冗余并不能让它变得更清晰。
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.
Edit: As SoapBox points out in a comment, they are compatible with C++ classes such as unique_ptr, shared_ptr, 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.
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.
The reason for this is that the NULL macro is deceptive (as nearly all macros are) it is actually 0 literal, not a unique type as the name suggests it might be. Avoiding macros is one of the general guidelines in C++. On the other hand, 0 looks like an integer and it is not when compared to or assigned to pointers. Personally I could go either way, but typically I skip the explicit comparison (though some people dislike this which is probably why you have a contributor suggesting a change anyway).
Regardless of personal feelings this is largely a choice of least evil as there isn't one right method.
This is clear and a common idiom and I prefer it, there is no chance of accidentally assigning a value during the comparison and it reads clearly:
if (some_ptr) {}
This is clear if you know that some_ptr is a pointer type, but it may also look like an integer comparison:
if (some_ptr != 0) {}
This is clear-ish, in common cases it makes sense... But it's a leaky abstraction, NULL is actually 0 literal and could end up being misused easily:
if (some_ptr != NULL) {}
C++11 has nullptr which is now the preferred method as it is explicit and accurate, just be careful about accidental assignment:
if (some_ptr != nullptr) {}
Until you are able to migrate to C++0x I would argue it's a waste of time worrying about which of these methods you use, they are all insufficient which is why nullptr was invented (along with generic programming issues which came up with perfect forwarding.) The most important thing is to maintain consistency.
In C
C is a different beast.
In C NULL can be defined as 0 or as ((void *)0), C99 allows for implementation defined null pointer constants. So it actually comes down to the implementation's definition of NULL and you will have to inspect it in your standard library.
Macros are very common and in general they are used a lot to make up for deficiencies in generic programming support in the language and other things as well. The language is much simpler and reliance on the preprocessor more common.
From this perspective I'd probably recommend using the NULL macro definition in C.
请注意,在 C++0x 中,我们可以执行 if (ptr == nullptr),这对我来说 读起来确实更好。 (再说一次,我讨厌这个宏。但是 nullptr 很好。)不过,我仍然使用 if (ptr),只是因为这是我习惯的。
I use if (ptr), but this is completely not worth arguing about.
I like my way because it's concise, though others say == NULL makes it easier to read and more explicit. I see where they're coming from, I just disagree the extra stuff makes it any easier. (I hate the macro, so I'm biased.) Up to you.
I disagree with your argument. If you're not getting warnings for assignments in a conditional, you need to turn your warning levels up. Simple as that. (And for the love of all that is good, don't switch them around.)
Note in C++0x, we can do if (ptr == nullptr), which to me does read nicer. (Again, I hate the macro. But nullptr is nice.) I still do if (ptr), though, just because it's what I'm used to.
int f(void* p)
{
if (!p) { return -1; }
// p is not null
return 0;
}
这样,您就可以避免“箭头代码。”
Frankly, I don't see why it matters. Either one is quite clear and anyone moderately experienced with C or C++ should understand both. One comment, though:
If you plan to recognize the error and not continue executing the function (i.e., you are going to throw an exception or return an error code immediately), you should make it a guard clause:
int f(void* p)
{
if (!p) { return -1; }
// p is not null
return 0;
}
Personally I've always used if (ptr == NULL) because it makes my intent explicit, but at this point it's just a habit.
Using = in place of == will be caught by any competent compiler with the correct warning settings.
The important point is to pick a consistent style for your group and stick to it. No matter which way you go, you'll eventually get used to it, and the loss of friction when working in other people's code will be welcome.
还有一点支持 foo == NULL 实践: 如果 foo 是一个 int * 或 bool *,那么 if (foo) 检查可以读者无意中将其解释为测试受指点的值,即 if (*foo)。这里的 NULL 比较提醒我们正在讨论的是指针。
但我认为良好的命名约定会使这个论点变得毫无意义。
Just one more point in favor of the foo == NULL practice: If foo is, say, an int * or a bool *, then the if (foo) check can accidentally be interpreted by a reader as testing the value of the pointee, i.e. as if (*foo). The NULL comparison here is a reminder that we're talking about a pointer.
But I suppose a good naming convention makes this argument moot.
大多数时候,您检查指针,然后执行您想要的操作,然后解决错误情况。结果可能是带有多个 if 的丑陋的 x 次缩进代码。
Actually, I use both variants.
There are situations, where you first check for the validity of a pointer, and if it is NULL, you just return/exit out of a function. (I know this can lead to the discussion "should a function have only one exit point")
Most of the time, you check the pointer, then do what you want and then resolve the error case. The result can be the ugly x-times indented code with multiple if's.
If style and format are going to be part of your reviews, there should be an agreed upon style guide to measure against. If there is one, do what the style guide says. If there's not one, details like this should be left as they are written. It's a waste of time and energy, and distracts from what code reviews really ought to be uncovering. Seriously, without a style guide I would push to NOT change code like this as a matter of principle, even when it doesn't use the convention I prefer.
And not that it matters, but my personal preference is if (ptr). The meaning is more immediately obvious to me than even if (ptr == NULL).
Maybe he's trying to say that it's better to handle error conditions before the happy path? In that case I still don't agree with the reviewer. I don't know that there's an accepted convention for this, but in my opinion the most "normal" condition ought to come first in any if statement. That way I've got less digging to do to figure out what the function is all about and how it works.
The exception to this is if the error causes me to bail from the function, or I can recover from it before moving on. In those cases, I do handle the error first:
if (error_condition)
bail_or_fix();
return if not fixed;
// If I'm still here, I'm on the happy path
By dealing with the unusual condition up front, I can take care of it and then forget about it. But if I can't get back on the happy path by handling it up front, then it should be handled after the main case because it makes the code more understandable. In my opinion.
But if it's not in a style guide then it's just my opinion, and your opinion is just as valid. Either standardize or don't. Don't let a reviewer pseudo-standardize just because he's got an opinion.
这是两种语言的基本原理之一,指针计算为可用作控制表达式的类型和值,C++ 中的 bool 和 C 中的 int。只需使用它。
This is one of the fundamentals of both languages that pointers evaluate to a type and value that can be used as a control expression, bool in C++ and int in C. Just use it.
我使用过的大多数编译器至少会在没有进一步语法糖的情况下对 if 赋值发出警告,所以我不相信这个论点。也就是说,我专业地使用过这两种产品,并且对其中任何一种都没有偏好。在我看来, == NULL 绝对更清晰。
Most compilers I've used will at least warn on the if assignment without further syntax sugar, so I don't buy that argument. That said, I've used both professionally and have no preference for either. The == NULL is definitely clearer though in my opinion.
发布评论
评论(14)
根据我的经验,首选
if (ptr)
或if (!ptr)
形式的测试。它们不依赖于符号NULL
的定义。他们不会暴露意外分配的机会。而且它们清晰简洁。编辑: 正如 SoapBox 在评论中指出的那样,它们与 C++ 类兼容,例如
unique_ptr、shared_ptr、auto_ptr
这些对象充当指针并提供到bool
来启用这个习惯用法。对于这些对象,与 NULL 的显式比较必须调用指针转换,这可能会产生其他语义副作用,或者比简单的存在检查(布尔值)更昂贵。转换意味着。我更喜欢代码能够表达其含义,而无需不必要的文本。
if (ptr != NULL)
与if (ptr)
具有相同的含义,但代价是冗余的特异性。下一个合乎逻辑的事情是编写if ((ptr != NULL) == TRUE)
,这样就很疯狂。 C语言明确通过if
、while
等测试的布尔值有特定的含义,非零值为真,零为假。冗余并不能让它变得更清晰。In my experience, tests of the form
if (ptr)
orif (!ptr)
are preferred. They do not depend on the definition of the symbolNULL
. They do not expose the opportunity for the accidental assignment. And they are clear and succinct.Edit: As SoapBox points out in a comment, they are compatible with C++ classes such as
unique_ptr, shared_ptr, auto_ptr
that are objects that act as pointers and which provide a conversion tobool
to enable exactly this idiom. For these objects, an explicit comparison toNULL
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 thebool
conversion implies.I have a preference for code that says what it means without unneeded text.
if (ptr != NULL)
has the same meaning asif (ptr)
but at the cost of redundant specificity. The next logical thing is to writeif ((ptr != NULL) == TRUE)
and that way lies madness. The C language is clear that a boolean tested byif
,while
or the like has a specific meaning of non-zero value is true and zero is false. Redundancy does not make it clearer.if (foo)
已经足够清楚了。使用它。if (foo)
is clear enough. Use it.我将从这个开始:一致性才是王道,决策并不比代码库的一致性重要。
在 C++ 中,
NULL 在 C++ 中定义为
0
或0L
。如果您读过《C++ 编程语言》Bjarne Stroustrup 建议使用
0< /code> 在进行赋值时显式地避免
NULL
宏,我不确定他是否在比较方面做了同样的事情,自从我读这本书以来已经有一段时间了,我认为他只是做了
if(some_ptr)
没有进行明确的比较,但我对此很模糊。原因是
NULL
宏具有欺骗性(几乎所有宏都是如此),它实际上是0
文字,而不是顾名思义的唯一类型。避免使用宏是 C++ 中的一般准则之一。另一方面,0
看起来像一个整数,但与指针比较或分配给指针时却不是。就我个人而言,我可以选择任何一种方式,但通常我会跳过显式比较(尽管有些人不喜欢这样做,这可能就是为什么你有贡献者建议进行更改的原因)。不管个人感受如何,这在很大程度上是一种最不邪恶的选择,因为没有一种正确的方法。
这很清楚,是一个常见的习惯用法,我更喜欢它,在比较过程中不会意外分配值,并且读起来很清楚:
如果您知道
some_ptr
是指针类型,那么这很清楚,但是它也可能看起来像一个整数比较:这很清楚,在常见情况下它是有意义的......但这是一个有漏洞的抽象,
NULL
实际上是0
文字并且可能最终很容易被滥用:C++11 有
nullptr
,它现在是首选方法,因为它明确且准确,只是要小心意外赋值:直到您能够迁移到 C++ 0x 我认为担心你使用这些方法中的哪一个是浪费时间,它们都是不够的,这就是发明 nullptr 的原因(以及提出完美转发的通用编程问题。)最重要的是保持一致性。
在CC中,
C是一个不同的野兽。
在 C 中,
NULL
可以定义为0
或((void *)0)
,C99 允许实现定义空指针常量。因此,它实际上取决于NULL
的实现定义,您必须在标准库中检查它。宏非常常见,通常它们被大量使用来弥补语言和其他方面的通用编程支持的缺陷。语言更加简单,对预处理器的依赖也更加普遍。
从这个角度来看,我可能会建议在 C 中使用
NULL
宏定义。I'll start off with this: consistency is king, the decision is less important than the consistency in your code base.
In C++
NULL is defined as
0
or0L
in C++.If you've read The C++ Programming Language Bjarne Stroustrup suggests using
0
explicitly to avoid theNULL
macro when doing assignment, I'm not sure if he did the same with comparisons, it's been a while since I read the book, I think he just didif(some_ptr)
without an explicit comparison but I am fuzzy on that.The reason for this is that the
NULL
macro is deceptive (as nearly all macros are) it is actually0
literal, not a unique type as the name suggests it might be. Avoiding macros is one of the general guidelines in C++. On the other hand,0
looks like an integer and it is not when compared to or assigned to pointers. Personally I could go either way, but typically I skip the explicit comparison (though some people dislike this which is probably why you have a contributor suggesting a change anyway).Regardless of personal feelings this is largely a choice of least evil as there isn't one right method.
This is clear and a common idiom and I prefer it, there is no chance of accidentally assigning a value during the comparison and it reads clearly:
This is clear if you know that
some_ptr
is a pointer type, but it may also look like an integer comparison:This is clear-ish, in common cases it makes sense... But it's a leaky abstraction,
NULL
is actually0
literal and could end up being misused easily:C++11 has
nullptr
which is now the preferred method as it is explicit and accurate, just be careful about accidental assignment:Until you are able to migrate to C++0x I would argue it's a waste of time worrying about which of these methods you use, they are all insufficient which is why nullptr was invented (along with generic programming issues which came up with perfect forwarding.) The most important thing is to maintain consistency.
In C
C is a different beast.
In C
NULL
can be defined as0
or as((void *)0)
, C99 allows for implementation defined null pointer constants. So it actually comes down to the implementation's definition ofNULL
and you will have to inspect it in your standard library.Macros are very common and in general they are used a lot to make up for deficiencies in generic programming support in the language and other things as well. The language is much simpler and reliance on the preprocessor more common.
From this perspective I'd probably recommend using the
NULL
macro definition in C.我使用
if (ptr)
,但这完全不值得争论。我喜欢我的方式,因为它很简洁,尽管其他人说
== NULL
使其更易于阅读且更明确。我知道它们来自哪里,我只是不同意额外的东西会让事情变得更容易。 (我讨厌宏观,所以我有偏见。)由你决定。我不同意你的论点。如果您没有收到条件作业的警告,则需要调高警告级别。就这么简单。 (出于对所有美好事物的热爱,请不要调换它们。)
请注意,在 C++0x 中,我们可以执行
if (ptr == nullptr)
,这对我来说 读起来确实更好。 (再说一次,我讨厌这个宏。但是nullptr
很好。)不过,我仍然使用if (ptr)
,只是因为这是我习惯的。I use
if (ptr)
, but this is completely not worth arguing about.I like my way because it's concise, though others say
== NULL
makes it easier to read and more explicit. I see where they're coming from, I just disagree the extra stuff makes it any easier. (I hate the macro, so I'm biased.) Up to you.I disagree with your argument. If you're not getting warnings for assignments in a conditional, you need to turn your warning levels up. Simple as that. (And for the love of all that is good, don't switch them around.)
Note in C++0x, we can do
if (ptr == nullptr)
, which to me does read nicer. (Again, I hate the macro. Butnullptr
is nice.) I still doif (ptr)
, though, just because it's what I'm used to.坦白说,我不明白为什么这很重要。其中任何一个都非常清楚,任何有一定 C 或 C++ 经验的人都应该理解两者。不过,有一点评论:
如果您打算识别错误并且不继续执行该函数(即,您将抛出异常或立即返回错误代码),则应该将其设为一个保护子句:
这样,您就可以避免“箭头代码。”
Frankly, I don't see why it matters. Either one is quite clear and anyone moderately experienced with C or C++ should understand both. One comment, though:
If you plan to recognize the error and not continue executing the function (i.e., you are going to throw an exception or return an error code immediately), you should make it a guard clause:
This way, you avoid "arrow code."
就我个人而言,我一直使用 if (ptr == NULL) ,因为它使我的意图明确,但目前这只是一种习惯。
使用
=
代替==
将会被具有正确警告设置的任何有能力的编译器捕获。重要的一点是为你的团队选择一致的风格并坚持下去。无论你走哪条路,你最终都会习惯它,并且在使用其他人的代码时减少摩擦将是受欢迎的。
Personally I've always used
if (ptr == NULL)
because it makes my intent explicit, but at this point it's just a habit.Using
=
in place of==
will be caught by any competent compiler with the correct warning settings.The important point is to pick a consistent style for your group and stick to it. No matter which way you go, you'll eventually get used to it, and the loss of friction when working in other people's code will be welcome.
还有一点支持 foo == NULL 实践:
如果
foo
是一个int *
或bool *
,那么if (foo)
检查可以读者无意中将其解释为测试受指点的值,即if (*foo)
。这里的NULL
比较提醒我们正在讨论的是指针。但我认为良好的命名约定会使这个论点变得毫无意义。
Just one more point in favor of the
foo == NULL
practice:If
foo
is, say, anint *
or abool *
, then theif (foo)
check can accidentally be interpreted by a reader as testing the value of the pointee, i.e. asif (*foo)
. TheNULL
comparison here is a reminder that we're talking about a pointer.But I suppose a good naming convention makes this argument moot.
C 编程语言 (K&R) 会让您检查null == ptr 以避免意外赋值。
The C Programming Language (K&R) would have you check for null == ptr to avoid an accidental assignment.
实际上,我使用这两种变体。
在某些情况下,您首先检查指针的有效性,如果它为 NULL,则只需返回/退出函数。 (我知道这可能会引发“函数是否应该只有一个退出点”的讨论)
大多数时候,您检查指针,然后执行您想要的操作,然后解决错误情况。结果可能是带有多个 if 的丑陋的 x 次缩进代码。
Actually, I use both variants.
There are situations, where you first check for the validity of a pointer, and if it is NULL, you just return/exit out of a function. (I know this can lead to the discussion "should a function have only one exit point")
Most of the time, you check the pointer, then do what you want and then resolve the error case. The result can be the ugly x-times indented code with multiple if's.
如果风格和格式将成为您评论的一部分,则应该有一个商定的风格指南来衡量。如果有的话,请按照风格指南的说明进行操作。如果没有,这样的细节应该按原样保留。这是浪费时间和精力,并且会分散代码审查真正应该揭示的内容。说真的,如果没有风格指南,原则上我会坚持不更改这样的代码,即使它不使用我喜欢的约定。
这并不重要,但我个人的偏好是
if (ptr)
。对我来说,其含义甚至比if (ptr == NULL)
更明显。也许他想说的是,最好先处理错误情况,然后再走上幸福之路?在这种情况下,我仍然不同意审稿人的观点。我不知道对此有一个公认的约定,但在我看来,最“正常”的条件应该在任何 if 语句中首先出现。这样我就可以减少挖掘工作来弄清楚该函数的全部内容及其工作原理。
例外情况是,如果错误导致我退出该功能,或者我可以在继续之前从中恢复。在这些情况下,我确实会先处理错误:
通过预先处理异常情况,我可以处理它,然后忘记它。但是,如果我无法通过预先处理它来回到幸福的道路上,那么应该在主要情况之后处理它,因为它使代码更容易理解。在我看来。
但如果它没有出现在风格指南中,那么这只是我的观点,你的观点同样有效。要么标准化,要么不标准化。不要仅仅因为审稿人有意见就让他伪标准化。
If style and format are going to be part of your reviews, there should be an agreed upon style guide to measure against. If there is one, do what the style guide says. If there's not one, details like this should be left as they are written. It's a waste of time and energy, and distracts from what code reviews really ought to be uncovering. Seriously, without a style guide I would push to NOT change code like this as a matter of principle, even when it doesn't use the convention I prefer.
And not that it matters, but my personal preference is
if (ptr)
. The meaning is more immediately obvious to me than evenif (ptr == NULL)
.Maybe he's trying to say that it's better to handle error conditions before the happy path? In that case I still don't agree with the reviewer. I don't know that there's an accepted convention for this, but in my opinion the most "normal" condition ought to come first in any if statement. That way I've got less digging to do to figure out what the function is all about and how it works.
The exception to this is if the error causes me to bail from the function, or I can recover from it before moving on. In those cases, I do handle the error first:
By dealing with the unusual condition up front, I can take care of it and then forget about it. But if I can't get back on the happy path by handling it up front, then it should be handled after the main case because it makes the code more understandable. In my opinion.
But if it's not in a style guide then it's just my opinion, and your opinion is just as valid. Either standardize or don't. Don't let a reviewer pseudo-standardize just because he's got an opinion.
这是两种语言的基本原理之一,指针计算为可用作控制表达式的类型和值,C++ 中的
bool
和 C 中的int
。只需使用它。This is one of the fundamentals of both languages that pointers evaluate to a type and value that can be used as a control expression,
bool
in C++ andint
in C. Just use it.我非常喜欢这样一个事实:C/C++ 不会检查
if
、for
和while
语句中布尔条件的类型。我总是使用以下内容:即使是整数或其他转换为 bool 的类型:
这种风格的编码对我来说更具可读性和更清晰。只是我个人的意见。
最近,在使用 OKI 431 微控制器时,我注意到以下内容:
比以下情况更有效,
因为在后面的情况下,编译器必须将 chx 的值与 1 进行比较。其中 chx 只是一个真/假标志。
I'm a huge fan of the fact that C/C++ doesn't check types in the boolean conditions in
if
,for
andwhile
statements. I always use the following:even on integers or other type that converts to bool:
Coding in this style is more readable and clearer to me. Just my personal opinion.
Recently, while working on OKI 431 microcontroller, I've noticed that the following:
is more efficient than
because in later case the compiler has to compare the value of chx to 1. Where chx is just a true/false flag.
if (foo = bar)
时,现代 C/C++ 编译器会发出警告。因此我更喜欢
或者
但是,如果我正在编写一套风格指南,我不会在其中放入这样的内容,我会放入以下内容:
if (foo = bar)
by accident.Therefore I prefer
or
However, if I were writing a set of style guidelines I would not be putting things like this in it, I would be putting things like:
我使用过的大多数编译器至少会在没有进一步语法糖的情况下对
if
赋值发出警告,所以我不相信这个论点。也就是说,我专业地使用过这两种产品,并且对其中任何一种都没有偏好。在我看来,== NULL
绝对更清晰。Most compilers I've used will at least warn on the
if
assignment without further syntax sugar, so I don't buy that argument. That said, I've used both professionally and have no preference for either. The== NULL
is definitely clearer though in my opinion.