2

This is a pretty basic question, but I could not find a clear answer: is it allowed to check that a pointer is not null and (&&) to also check one of its members value in the same if statement?

Rephrased: is the right part of the condition in the example below even evaluated if f is null?

I know this works in VS current version, but what I need to know is if this is allowed by the C++ standard (or if it's UB). 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?

struct foo 
{
   bool bar;
};

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

Edit: the question is different from this one because it's not obvious that it's simply a matter of order: the proof is I did not end on that SO answer when I googled my question.

L.C.
  • 1,098
  • 10
  • 21
  • 4
    Does this answer your question? ["IF" argument evaluation order?](https://stackoverflow.com/questions/7925479/if-argument-evaluation-order) TL;DR it is correct, standard specifies that evaluation order is left to right – pptaszni Apr 28 '21 at 09:49
  • 1
    `"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?"` -- This question does not make sense, as the instructions emitted by the compiler do not use `if` statements. You can be reasonably certain that the compiler will not care whether you use one or two `if` statements. It will likely produce the same code, provided that you have compiler optimizations enabled. – Andreas Wenzel Apr 28 '21 at 09:55
  • @pptaszni: partly yes, thanks. Andreas: you're right, I meant if my 2 if-s get compiled as 2 conditional jump or just 1... but you got it right, right? – L.C. Apr 28 '21 at 10:06

2 Answers2

2

...is it allowed to check that a pointer is not null and (&&) to also check one of its members value in the same if statement?

It's perfectly valid, it is not UB, the expression is evaluated from left to right, if the left part of the expression evaluates to false the right part is not evaluated. This is usually called operator short circuit.

The rationale is that if the first part is false, there is no possibilty of the whole expression being true, false && false is false, false && true is also false.

...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?

In light of the above answer, you wouldn't need two ifs, I would argue that it will not make your code more readable, I prefer the way you have it right know, in any case this is only my opinion. About the compiler, I wouldn't think that there will be much difference either way, as sampled in this live demo.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
1

is it allowed to check that a pointer is not null and (&&) to also check one of its members value in the same if statement?

Yes.

is the right part of the condition in the example below even evaluated if f is null?

No.

what I need to know is if this is allowed by the C++ standard

Yes.

(or if it's UB)

No.

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?

I would expect it. Seems like a trivial optimisation. Note that in cases where the && operator is overloaded (which never is in the case of pointers), such change can change the meaning of the program.


Standard quote (latest draft):

[expr.log.and]

The && operator groups left-to-right. The operands are both contextually converted to bool. The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

eerorika
  • 232,697
  • 12
  • 197
  • 326