4

Is the left part of the && always evaluated before the right part?

I want to know because I'm wondering if I can change

if(i > 0)
    if(someFunc(arr[i-1], arr[i]))
        //do work

to

if(i > 0 && someFunc(arr[i-1], arr[i]))

or would this cause undefined behaviour if the right side gets evaluated first and arr[0-1]is referenced?

Celeritas
  • 14,489
  • 36
  • 113
  • 194

2 Answers2

3

Yes, because of short-circuit behavior of logical && operator, in case of && second expression evaluates only when first is true. Read following:

6.5.13 Logical AND operator

4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares equal to 0, the second operand is not evaluated.

From Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

So if i > 0 is false (for example if i = 0) then result of i > 0 expression will be false, and then second operand someFunc(arr[i-1], arr[i] will not be called (evaluated).

Accordingly, if(i > 0 && someFunc(arr[i-1], arr[i])) is safe to code, but be-careful i - 1 shouldn't be > max index value of arr[]. Really I will prefer this form of if compare to nested if blocks (flat is better then nested).

From @Maroun Maroun's answer "Is there any reason for asking if(1 || Foo())?" Additional information that might help you:

  • if(a && b) - if a is false, b won't be checked.
  • if(a && b) - if a is true, b will be checked, because if it's false, the expression will be false.
  • if(a || b) - if a is true, b won't be checked, because this is true anyway.
  • if(a || b) - if a is false, b will be checked, because if b is true then it'll be true.
Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
1

Yes. Order of evaluation for the operators &&, ||, , and ? :(ternary operator) are guaranteed from left to right. A sequence point occurs between the left and right sub-expression of these operands. All the side effects of the left sub-expression of these operators (&&, || and ,) are completed before any access to its right sub-expression.

would this cause undefined behavior if the right side gets evaluated first and arr[0-1] is referenced?

Yes. If that were the case, it would cause undefined behavior. (But it doesn't happen that way, so there won't be any undefined behavior.)

haccks
  • 104,019
  • 25
  • 176
  • 264