【问题标题】:Checking null pointer && pointer->member value in the same if statement在同一 if 语句中检查空指针 && 指针-> 成员值
【发布时间】:2021-04-28 09:46:58
【问题描述】:

这是一个非常基本的问题,但我找不到明确的答案: 是否允许检查指针不为空并且 (&&) 在同一 if 语句中也检查其成员值之一?

改写:如果 f 为空,下例中条件的右侧部分是否也被评估?

我知道这适用于 VS 当前版本,但我需要知道的是 C++ 标准是否允许这样做(或者它是否是 UB)。 另外,如果我将其编写为 2 个单独的 if 以使其更具可读性,我可以期望编译器将其优化为单个 if 吗?

struct foo 
{
   bool bar;
};

void main(){
   foo *f;
   // DO THINGS 
   if (f != null && f->bar == true)
   {
      // DO THINGS
   }
}

编辑:这个问题与this one 不同,因为这只是一个顺序问题并不明显:证明是当我用谷歌搜索我的问题时,我并没有以那个 SO 答案结束。

【问题讨论】:

  • 这能回答你的问题吗? "IF" argument evaluation order? TL;DR 是正确的,标准规定评估顺序是从左到右
  • "Also, if I write it as 2 separate if to make it more readable, can I expect the compiler to optimize it into a single if?" -- 这个问题没有意义,因为编译器发出的指令不使用if 语句。您可以合理地确定编译器不会关心您是使用一个还是两个if 语句。如果您启用了编译器优化,它可能会生成相同的代码。
  • @pptaszni:部分是的,谢谢。安德烈亚斯:你说得对,我的意思是如果我的 2 个 if-s 被编译为 2 个条件跳转或只是 1...但你没看错,对吧?

标签: c++ language-lawyer


【解决方案1】:

...是否允许在同一个 if 语句中检查指针是否为空并且 (&&) 也检查其成员值之一?

It's perfectly valid, it is not UB,表达式从左到右计算,如果表达式的左边部分计算为false,则不计算右边部分。这通常称为操作员短路。

理由是,如果第一部分是false,则整个表达式不可能是truefalse && falsefalsefalse && true 也是false

...如果我将其编写为 2 个单独的 if 以使其更具可读性,我可以期望编译器将其优化为单个 if 吗?

根据上述答案,您不需要两个ifs,我认为它不会使您的代码更具可读性,我更喜欢您正确知道的方式,无论如何这只是我的意见。关于编译器,我认为这两种方式都不会有太大差异,正如live demo 中的示例。

【讨论】:

    【解决方案2】:

    是否允许在同一个 if 语句中检查指针是否为空并且 (&&) 也检查其成员值之一?

    是的。

    如果 f 为空,下面的例子中的条件是否正确?

    没有。

    我需要知道的是 C++ 标准是否允许这样做

    是的。

    (或者如果是 UB)

    没有。

    另外,如果我把它写成 2 个单独的 if 以使其更具可读性,我可以期望编译器将它优化成一个 if 吗?

    我会期待的。似乎是一个微不足道的优化。请注意,在 && 运算符重载的情况下(在指针的情况下绝不会如此),这样的更改可能会改变程序的含义。


    标准报价(最新草案):

    [expr.log.and]

    && 运算符从左到右分组。 操作数都根据上下文转换为布尔值。 如果两个操作数都为真,则结果为真,否则为假。 与 & 不同,&& 保证从左到右的评估:如果第一个操作数为假,则不评估第二个操作数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-16
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      相关资源
      最近更新 更多