【问题标题】:Short-circuiting and readability短路和可读性
【发布时间】:2012-09-09 20:41:51
【问题描述】:

在这一行

if ((last_search == NULL) || (last_search != NULL && total_results != 0))

我知道 C 的短路评估规则说,只有当 last_search 不为空时,它才会尝试评估 || 的右侧,因此它相当于写作

if ((last_search == NULL) || (total_results != 0))

有人建议我使用后者,但前者不是更具可读性吗?编译器也不会优化掉多余的last_search != NULL吗?

【问题讨论】:

  • 不,是的。更少的代码就是更多。
  • 旁注:我宁愿将常量向左移动,(NULL == last_search)...
  • @a1ex07 我知道这只是个人喜好(而且我知道我最近看到了这种趋势),但对我来说,把常数放在左边会让它更难阅读。我把它读作“如果 NULL 等于 ...”,这是错误的,因为 NULL 是一个常量并且不会改变。 “如果 last_search 等于 ...”对我来说是一种更自然、更容易理解的读法。
  • 显而易见的事情不应该被提及..所以第一种情况,在某种程度上,只是有一些冗余。
  • @a1ex07 我认为将常量向左移动是个坏建议。您正在测试 last_search 值是否为 NULL 而不是 NULL 是否为 last_search 值。

标签: c if-statement conditional readability short-circuiting


【解决方案1】:

这是主观的,但不,第一个变体不是更具可读性,因为还有更多要阅读的内容。最易读的代码(也是最少的错误!)是不存在的代码。试想一下,如果您想一次检查 3 或 4 个条件会发生什么。

还有一个反例:你会写这样的代码吗?

if (number < 0) {
}
else if(number >= 0) {
    // why not just "else"?
}

至于性能:编译器可能会优化冗余调用,但撤消性能下降无助于可读性下降。

【讨论】:

  • +1。如果我想强调 number&gt;=0(例如在很长的 if 块之后),我将 elseif 的 if 部分移到评论中。
【解决方案2】:

不,不是。第二个更具可读性。为什么要保留冗余检查,不管编译器是否会优化它?

第一个版本告诉你 last_search 不是 NULL 因为它到达了那里,但如果你不能从第一个条件(last_search == NULL 失败)中看出这一点,你可能遇到比可读性更大的问题.

【讨论】:

  • +1 给你,因为这个答案和乔恩的一样好,但你没有得到任何支持,因为他有更多的代表......
  • @H2CO3 公平地说,我也赞成他“最易读的代码是不存在的代码。”。 :)
  • @H2CO3:等你看到当你回答一个问题时会发生什么,而 Jon Skeet 也做了同样的事情......顺便说一句,我也赞成这个,因为 Luchian 是第一个。
  • @Jon 去过那里。幸运的是,这种情况并不经常发生,我很少关注 Java(而 C# 离我很远)......
  • @Jon 是的,Jon Skeet 也是如此。每个人都支持他只是因为他是 Jon Skeet。如果是因为他有最好的答案,我不会介意。当然,在很大一部分情况下,他有最好的答案,但如果没有,那为什么呢?
【解决方案3】:

不仅短路评估使其难以阅读,而且还使用了多余的比较。

if ( !last_search || total_results)

比您建议的任何内容都更容易阅读。

【讨论】:

  • 如果NULL 的值不是false 怎么办? NULL 只是一个常数(我希望它是,无论如何 - 如果不是,这里会有更多问题),因此,实际上可能对应于不会被评估为假的东西。使用“if ((last_search == NULL) || total_results)”
  • @AJMansfield NULL 将始终评估为假。即使它的底层表示不是全零。
  • 指针值的转换以获得逻辑条件是由标准很好地定义的。它完全符合您的期望:当指针为空指针时,它是false。只需使用标准提供的工具即可。
  • @Dave NULL 这里不是编译器常量吗?如果它被用作占位符(例如-1)怎么办?虽然我同意如果是这样的话,代码的问题远不止这些。
  • 好的,谢谢,我对 C 不是很熟悉。感谢您的澄清。
猜你喜欢
  • 2017-02-26
  • 2020-07-22
  • 1970-01-01
  • 2021-01-04
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
相关资源
最近更新 更多