35

With reference to Comma-Separated return arguments in C function [duplicate] ,

x=x+2,x+1;

will be evaluated as

x=x+2; 

However, in case of the following code

#include<stdlib.h>
#include<stdio.h>

int fun(int x)
{
    return (x=x+2,x+1); //[A]
}

int main()
{
   int x=5;
   x=fun(x);
   printf("%d",x); // Output is 8
}

Shouldn't line [A],be evaluated as

x=x+2;

giving x = 7

Zoe
  • 27,060
  • 21
  • 118
  • 148
Ashish Kumar
  • 593
  • 4
  • 12
  • 4
    Command flow goes from left to right in this case, you can also try `while(x=2,x<3)` to verify this - it will be an infinite loop. – Gaurav Sep 14 '19 at 20:40
  • 15
    Thank you for demonstrating why we try to avoid the comma operator. – Nic Sep 15 '19 at 19:58
  • 1
    @Observer: Well I guess we can put the test in the middle of a few more loop forms than I though. – Joshua Sep 16 '19 at 02:30

7 Answers7

57

The statement return (x = x + 2, x + 1); is equivalent to:

x = x + 2; // x == 7
return x + 1; // returns 8
Nathan Xabedi
  • 1,097
  • 1
  • 11
  • 18
  • 8
    +1. And to directly address the OP's confusion: the statement `x = x + 2, x + 1;` is equivalent to the pair of statements `x = x + 2; x + 1;`. It's just that the statement `x + 1;` doesn't actually *do* anything, so we can just ignore that statement and say that it's equivalent to `x = x + 2;`. When you add a `return`, obviously the statement `return x + 1;` is no longer a no-op, so we can't ignore it anymore. :-) – ruakh Sep 15 '19 at 22:40
15

When writing return (x=x+2,x+1), the first expression is evaluated first so x=x+2 is evaluated, causing x to equal 7 as a side effect. Then the second expression is evaluated and returned, hence the function returns x+1 hence returns 8.

If you had written return (x+2,x+1);, the result would have been 6 because the first expression x+2 doesn't have any side effect.

Corentin Pane
  • 4,794
  • 1
  • 12
  • 29
  • why ```return (x=x+2,x+1)``` causes a side effect? – Ashish Kumar Sep 14 '19 at 20:46
  • 6
    @AshishKumar because it changes the value of `x`. Not really a "side effect" because it's still explicit, but it causes `x` to be different on the right side of the comma. – Matthieu Sep 14 '19 at 20:58
  • @AshishKumar The comma operator explicitly has a sequence point between the evaluation of the left and right operand. You are guaranteed that `x=x+2` is evaluated before `x+1`. Regardless, don't write crappy code like that and avoid `,` operator in general. – Lundin Sep 16 '19 at 11:39
12

Both parts in the return are evaluated respectively and the result of the last instruction is returned:

At first we have:

x = x + 2 // 7

Now x is updated to 7 before the second evaluation which gives:

x + 1 // 7 + 1 = 8

and finally return 8.

For better understanding consider the case of intermediate variable as follows:

return (y = x + 2, y + 1);
XBlueCode
  • 785
  • 3
  • 18
6

The QA you conveniently linked states

The comma operator evaluates a series of expressions. The value of the comma group is the value of the last element in the list.

so the value of

x+2,x+1;

is x+1 and there are no side effects.


Sample code:

#include<stdio.h>
int main(int argc, char * argv){
    int x;
    x = 0;
    x = (x+2, x+1);
    printf("%d\n", x);
    return 0;
}

results in 1 when run.


However, when you do

return (x=x+2, x+1)

you do have a side effect: x is incremented by two first, then x is incremented by 1 and the result is returned.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
3

As other users stated, the command flow goes from left to right, and in the case of return, it will give back the value in the rightmost operator. What is written before this operator and separated by commas is no different from line written expressions. Example:

return (x = x + 2, x = x - 5, x + 1);

The code below produces the same result:

x = x + 2;  
x = x - 5;
return x + 1;

For x = 0, this would return -2. Notice that, for both codes, if we change x = x - 5 to x - 5, i.e, we are subtracting 5 from x but not saving its result anywhere, the return value of x will change to 3 and, therefore, confirming the equivalency.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Egodev
  • 91
  • 5
3

That's a matter of operator precedence.

x=x+2,x+1 is evaluated as (x=x+2), (x+1) and not as x=(x+2,x+1)

RiaD
  • 46,822
  • 11
  • 79
  • 123
0

The comma operator introduces a sequence point in your code. The statements are evaluated in this order:

  1. x = x + 2, at which point the local x in fun is 7.

  2. x + 1, which evaluates to 8, and is returned.

To clarify, here's a parenthesized version showing operator precedence:

return (x=x+2),x+1;

The left-hand expression is evaluated and its value is thrown away. The right-hand expression's value is what is returned.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76