3

I'm struggling to understand the behavior of the below code:

#include <stdio.h>

int main(void)
{
    int i;
    int j;
    int k;

    i = 7;
    j = 8;
    k = 9;
    printf("%d\n", (i = j) || (j = k));
    printf("%d, %d, %d\n", i, j, k);

    return (0);
}

Output:

1
8, 8, 9

Question:

  • I understand that expr1 | | expr2 has the value 1 if either expr1 or expr2(or both)has a nonzero value.

  • The value of i increased from 7 to 8 because j's value is assigned to i but the same way why does the value of the j is not increased even though j = k? I was expecting an

output

1
8, 9, 9
Ajo Mathew
  • 101
  • 7
  • 8
    The `||` is a short circuit operator meaning it won't evaluate the right half it not necessary, like in this case – mousetail Jun 26 '21 at 06:58
  • 1
    `(i = j)` means you are assigning value of `j` to `i`. Are you trying to assign or compare? For comparison, use `==` operator instead. – kiner_shah Jun 26 '21 at 07:00
  • 1
    I suggest a read on operator precedence. – Sorenp Jun 26 '21 at 07:02
  • 1
    [Short circuit behavior of logical expressions in C in this example](https://stackoverflow.com/q/28145152/995714) – phuclv Jun 26 '21 at 07:21
  • 1
    @Sorenp "operator precedence" is not relevant here, there is only one way to parse the code as written . The issue is with short circuit evaluation – M.M Jun 26 '21 at 07:27
  • 1
    The short circuit behaviour can be used for error handling although generally not considered good style, e.g. `fread(b, 1, 500, fp) == 500 || printf("Read failed");` – M.M Jun 26 '21 at 07:29
  • @kiner_shah The OP already mentioned in the question that this is an assignment. The question is not why `i` is changed but why `j` is not. – Gerhardh Jun 26 '21 at 09:10

2 Answers2

5

From the C standard (emphasis mine):

Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

The above behaviour is commonly referred to as operator short circuiting.

In your example, since (i = j) is not zero the second operand is thus not evaluated.

kaylum
  • 13,833
  • 2
  • 22
  • 31
3

First of all,

true || true is true

true || false is true

false || true is true

false || false is false

So operator || is calculating the first expression and if it is true, it does not check the second one.

In yours particular situation (i = j) is equal to 8, which is considered true, because int values are considered false only if they are equal 0. So the second (j = k) is never computed, which leads to your result.

user3386109
  • 34,287
  • 7
  • 49
  • 68