Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wierd syntax with parentheses in C [duplicate]

I was given the code:

#include <stdio.h>
int main(void) {
    int a = 0, b = 0, c = 0;
    c = (a -= a - 5), (a = b, b + 3);
    printf("a = %d, b = %d, c = %d", a, b, c); // a = 0, b = 0, c = 5
}

and my task was to figure out how it works. I do not understand how the line

c = (a -= a - 5), (a = b, b + 3); 

works, though.

My guess is that it works just like this code:

#include <stdio.h>

int main(void) {
    int a = 0, b = 0, c = 0;
    a -= a - 5;
    c = a;
    a = b;
    b + 3;
    printf("a = %d, b = %d, c = %d", a, b, c); //a = 0, b = 0, c = 5
}

because the result is the same.

But I don't understand the first version of the code. So firstly, it changes the value of a (a becomes 5), then changes the value of c (c becomes a), and then it performs the expression in the second parentheses (which seems to not affect the value of c at all, although it's the same line of code and there was no semicolon in between, only a comma. what is that syntax? Is there a name for that kind of syntax? i just don't understand why it was written like that and why it does what it does.

Also, less importantly, what does the line:

b + 3;

do? Is it just nothing?

like image 855
xiushama Avatar asked Dec 07 '25 07:12

xiushama


2 Answers

There are two steps of determining how it works:

  • where are parentheses?
    • i.e. what is the associativity of operators?
    • see https://en.cppreference.com/w/c/language/operator_precedence
  • what happens when?
    • i.e. what is the order of execution of operations?
    • See https://en.cppreference.com/w/c/language/eval_order
    • If the order is not defined, the code is invalid.

The expression:

c = (a -= a - 5), (a = b, b + 3); 

= bonds more tightly than ,. It is parsed as:

( c = ( a -= (a - 5) ) ) , ( (a = b) , (b + 3) ); 

The , comma operator is first and executes left operand first. The result of the comma operator is equal to the right operand. See https://en.cppreference.com/w/c/language/operator_other#Comma_operator .

So first c = ( a -= (a - 5) ). On assignment = the both sides are "unsequenced" with each other, can be in any order. But in these cases, like a vs a - 5, nothing fancy happens on the left side of =. The result of assignment is the assigned value. See https://en.cppreference.com/w/c/language/operator_assignment .

Bottom line, the order of operation will be:

 ( c = ( a -= (a - 5) ) ) , ( (a = b) , (b + 3) )
1.             a - 5                               Evaluating right side of -=
2.             a                                   Evaluating the left side of - when doing -=
3.       a -=                                      Assignment to a
4. c =                                             Assignment to c
5.                                 b               Evaluating right side of =
6.                             a =                 Assignment to a
7.                                       b + 3     Evaluating just the value b + 3

With a small caveat that 1. and 2. operations are actually unsequenced. a maybe evaluated before a - 5, which doesn't change anything. Calculating, we will get:

   ( c = ( a -= (a - 5) ) ) , ( (a = b) , (b + 3) )
1.               0 - 5 = -5
2.           \= 0
3.         a = (0) - (-5) = 5
4.   c = 5
5.                                   0
6.                               a = 0
7.                                         0 + 3 = 3

The resulting assignment result will be: c = 5, a = 0 and the expression "returns" the value 3.

what is that syntax?

Comma operator is most probably confusing here.

what does the line b + 3; do? is it just nothing?

Yes, it does nothing.

like image 117
KamilCuk Avatar answered Dec 08 '25 21:12

KamilCuk


c = (a -= a - 5), (a = b, b + 3);

It is equivalent to:

a -= a - 5;
c = a

and

int temp = a - 5;
a -= temp;
c = a;

So c is equal to 5

Why?

Because you have two operators

c = (a -= a - 5), (a = b, b + 3);
^^^^^^^^^^^^^^^^  **************
      1st               2nd

The second part of the second one is simply no-op and is ignored by the compiler

If you wanted the whole comma to be evaluated, then you need to use another pair of parenthesises:

    c = ((a -= a - 5), (a = b, b + 3));
    //  ^                            ^ 

and the result will be 3.

like image 29
gulpr Avatar answered Dec 08 '25 20:12

gulpr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!