1

The program is posted below:

#include <stdio.h>

int main(void)
{
    int a, b, c, d;

    printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);

    if( (a = 4) || (b = 6) || (c = 7) || (d = 8) )
        printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
}

I understand the first printf statement but in the 2nd if statement I do not understand what it would evaluate when there is only one equal sign instead of two.

The output is :

        a = 0, b = 0, c = 32767, d = -341260496
        a = 4, b = 0, c = 32767, d = -341260496

So the 2nd if statement ended up being true but how?
I thought one equal sign would be assigning a value to the variables.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 3
    The first printf is undefined behavior, because you have not initialized any of the variables. – DYZ Jun 07 '17 at 21:23
  • 5
    None of the variables are initialized. In the end, only `a` gets set to `4` while the others still remain uninitialized. – Jeff Mercado Jun 07 '17 at 21:23
  • 3
    Use `==` to test for equality. `a = 4` assigns the value 4 to `a`. – r3mainer Jun 07 '17 at 21:24
  • 1
    Possible duplicate of [In C++ what causes an assignment to evaluate as true or false when used in a control structure?](https://stackoverflow.com/questions/2003895/in-c-what-causes-an-assignment-to-evaluate-as-true-or-false-when-used-in-a-con) – Spencer Wieczorek Jun 07 '17 at 21:24
  • 2
    one equal sign assigns then returns the assigned value (so it's `true` for the first assignment, the rest is skipped) – Jean-François Fabre Jun 07 '17 at 21:24
  • 2
    Only `a` gets assigned because it's a short circuit. There's no point in looking at anything past the first `||` so those other assignments don't get executed. – criticalfix Jun 07 '17 at 21:26
  • 1
    Possible duplicate of [Is short-circuiting logical operators mandated? And evaluation order?](https://stackoverflow.com/questions/628526/is-short-circuiting-logical-operators-mandated-and-evaluation-order) – t0mm13b Jun 07 '17 at 21:27

4 Answers4

5

I do not understand what if would evaluate when there is only one equal sign instead of two.

One equal sign makes it an assignment. Hence, a=4 evaluates to 4, which is interpreted as "true" by the logical "OR" operator ||. At this point no further evaluation is happening due to short-circuiting, so the remaining variables retain the values that they have prior to the if statement.

Note: Printing unassigned variables causes undefined behavior. You should change the declaration line as follows:

int a = 0, b = 0, c = 0, d = 0;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

This call of printf

    int a, b, c, d;

    printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);

has undefined behavior because variables a, b, c, and d are not initialized and have indeterminate values that can be trap values.

In the condition of the if statement

if( (a = 4) || (b = 6) || (c = 7) || (d = 8) )

there is assignment expression

a = 4

According to the C Standard (6.5.16 Assignment operators)

3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue...

And further (6.5.14 Logical OR operator)

3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int. 4 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.

Thus only the assignment

a = 4

will be performed in this if statement

if( (a = 4) || (b = 6) || (c = 7) || (d = 8) )

all other variables still will be uninitialized.

As the value of the assignment that is 4 is not equal to 0 then the if sub-statement will be executed.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

So the 2nd if statement ended up being true but how?

In C, assignments are also a sort of expression that evaluate to some value. The value is (in most situations) the right hand side of the assignment.

In this case, (a = 4) evaluates to 4, which is true in the world of C, thus short-circuiting the entire condition and skipping the assignments for b, c and d. Which is why only a is initialised while the others retain their junk values.

cs95
  • 379,657
  • 97
  • 704
  • 746
1

In short, when you compare using OR, evaluation is done until the 1st occurrence of TRUE. So only a=4 is assigned. Rest are still uninitialized.

Pushan Gupta
  • 3,697
  • 5
  • 23
  • 39