Precedence order for a complex expression [duplicate] - c

This question already has answers here:
Assignment of two values in parentheses in C
(3 answers)
Closed 2 years ago.
#include<stdio.h>
void main()
{
int num, var;
num = (var=15, var+=35);
printf("%d",num);
}
here num evaluates as 50. I want to verify
My reasoning :- inside (..), we first read from left to right to see all operands available, make an order of preference, then evaluate += = , (in order). Finally we have var=50, which gets assigned to num. Am I correct?

The expression
(var=15, var+=35)
uses the comma operator, which evaluates each subexpression from left to right. The comma introduces a sequence point, so the side effects of each subexpression are applied before the next subexpression is evaluated. The type and result of the expression is the type and result of the rightmost subexpression. It's equivalent to writing:
var = 15;
var += 35;
num = var;
Please note that the comma operator used above is not the same as the comma that separates arguments in a function call - function arguments are not guaranteed to be evaluated from left to right, and side effects are only guaranteed to be applied before the function is called, not after each argument is evaluated.

Related

C language and operators [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 1 year ago.
#include <stdio.h>
int main()
{
int i=2;
if(i==3,4)
{
printf("If block");
}
else
{
printf("Else block");
}
return 0;
}
Why is this code returning "If block" ?``
The expression in the if statement:
(i==3,4)
Contains the comma operator. It evaluates its left operand, discards its value, then evaluated the right operand which is its result. This operator also has lower precedence than the equality operator ==, so this parses as:
((i==3),4)
So i==3 is first evaluated. Since i has the value 2 the comparison is false resulting in i==3 evaluating to 0. This value is discarded. Then 4 is evaluated which becomes the value of the entire expression. Since this value is non-zero, the if block is true, so "If block" is printed.
In the condition of the if statement
if(i==3,4)
there is used the comma operator.
From the C Standard (6.5.17 Comma operator)
2 The left operand of a comma operator is evaluated as a void
expression; there is a sequence point between its evaluation and that
of the right operand. Then the right operand is evaluated; the result
has its type and value
That is the above if statement can be equivalently written like
if( ( i==3 ), ( 4 ))
So according to the quote from the C Standard the left operand ( i == 3 ) is evaluated as a void expression that is its result is discarded. And the result of the whole expression is the value of the right operand that is of the expression ( 4 ). As this expression is not equal to 0 then the whole condition is evaluated as logical true and the sub-statement of the if statement is executed.
"Why is this code returning "If block" ?``"
The explanation of why the expression if(i==3,4) causes execution flow to go to the true branch is provided in good detail in the other answers. In short the idea that it evaluates its first operand and discards the result, Then uses the second operand to evaluate as the condition.
But, some might ask is this useful?
One use is to force a side effect prior to deciding which branch to flow to.
For example
if (numeric_read(str, &err), !err)
// ^ ^ result 'err' of side effect used in if evaluation.
^
// causes side effect by call function which assigns value to err.
(credit, in comments.)
The side effect here populates err, then discards the logical result of the call in the first argument. The value assigned to err is then used to select the branch.

Assigning multiple integers separated by comma to an int in C - Why does that work? What for? [duplicate]

This question already has answers here:
C comma operator
(4 answers)
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
I saw this in an exam and when I tried it out I was surprised. I tried it online and it works too. So I think it is the C language.
Why is that working? What is the use case for such an assignment syntax?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int i = (1,2,3,4,5);
printf("%d", i);
return 0;
}
These are not "multiple integers", but a comma operator. The whole parenthesised part is a single expression with each sub-expression (separated by commas) evaluated strictly from left to right. The results of all but the rightmost subexpression are ignored. The result of the whole expression is that of the last (rightmost) expression. Here it is the integer value 5.
Note that this operator is mostly used where only a single expression is allowed to add further side-effects. E.g. in a loop like:
int cnt = 0;
for ( const char *cp = "Hello" ; *cp != '\0' ; cp++, cnt++ ) ;
This counts the number of characters in a C-string, incrementing the pointer and cnt after each iteration. The results are ignored here.
So, this is in no way related to tuples or similar like in Python. There are actually no cases the usage of this operator is unavoidable and it should be used with caution — and some coding standards forbid its usage.
That's the comma operator at work. It evaluates the expression on its left-hand side, creates a sequence point, discards the value of the expression, then evaluates the expression on the right-hand side, and returns that as the value. When there are multiple expressions as in the example, then each is evaluated in turn and only the last is kept. With the sample, the compiler does the evaluation because every value is known at compile time. Note that the argument list to a function is not a use of the comma operator.
That isn't a valid use-case for the comma operator. What might be a more nearly valid use-case would be some operations with side-effects (such as function calls) that need to be sequenced and the final value assigned:
int i = (getchar(), getchar(), getchar());
This sets i to the third character in standard input, or EOF if there are not three characters left in the standard input to be read. Still not a realistic use-case, but better than assigning a list of constants.
In addition to the other answers, you need to watch for instances where a , is the comma operator as opposed to when it is a separator. For example, the following is invalid:
int i = 1,2,3,4,5;
In this case, the , is a separator between variable declarations. It declares i as an int and initializes it to 1, then it attempts to parse 2 as a variable name, which fails.
It works because you're using the "comma operator", which evaluates the subexpressions on the left and right, and has the value from the right-hand expression.
So in (1,2,3,4,5), 1 is evaluated and the result is discarded, then 2,3,4,5... in which (because of the next comma) 2 is evaluated and the result discarded, then 3,4,5... in which 3 is evaluated and discarded, then 4,5... in which 4 is evaluated and discarded, then 5 which becomes the result of the expression.
As for when it's useful, mainly as a shortcut when you need to evaluate several (sub)expressions for their side effects but aren't interested in their values (except maybe the last one). It's sometimes convenient in for loop expressions, such as when incrementing two variables:
for (i=0,j=1; j < len; i++,j++) {
..where it appears in both the initialization expression and the loop expression.
Why is that working?
Because its a valid C syntax. The comma in (1,2,3,4,5) are comma operator
C11: 6.5.17 Comma operator
Syntax
1 expression:
assignment-expression
expression , assignment-expression
Semantics
2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.114)
What is the use case for such an assignment syntax?
See the example below
3 EXAMPLE As indicated by the syntax, the comma operator (as described in this subclause) cannot appear in contexts where a comma is used to separate items in a list (such as arguments to functions or lists of initializers). On the other hand, it can be used within a parenthesized expression or within the second
expression of a conditional operator in such contexts. In the function call
f(a, (t=3, t+2), c)
the function has three arguments, the second of which has the value 5.

What does comma operator in C do when we return an integer with two values? [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
I was actually returning a float value when I typed , instead of . but it did not give me any error. Then I tried running the below code.
#include<stdio.h>
#include<conio.h>
int getValue();
int main()
{
int a = getValue();
printf("%d", a);
return 0;
}
int getValue()
{
return 2, 3;
}
Now the output is 3, that is it returned the second value. This happened two years ago and was searching for the proper answer since then.
Studying answers to this question I came to know that it returns the second value after evaluating, but what does it do with the first one?
I studied the logic of the stack(how the values are pushed and pop internally) but I don't think this have anything to do with it.
Does it processes the two values or do something else?
Quoting C11 standard, chapter §6.5.17, Comma operator
The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.
Now, to answer your question
what does it do with the first one?
we can say, the first operand (left hand operand) is evaluated and the result is discarded.
NOTE: I mentioned the result, not the effect.
Just to clarify, in your case, you won't notice the effect, but you can notice it's effect if both the left and right hand expressions are related to the same variable. For example, let's discuss a simple exmple
return p=3, p+2;
We can break down the return statement like
asign a value 3 to the variable p [left hand side operator of ,]
execute p+2, ehich generates a value of 5. [right hand side operator of ,]
return the value 5 as the value of second argument [following the clause : "the result (of , operator) has its (evaluation of right-operand) type and value."]
See a live demo.
comma operator will evaluate from left to right and return the right most expression or value. This is equivalent to:
int getValue()
{
(void)2;
return 3;
}

Can't understand the output of C progaram [duplicate]

This question already has answers here:
Using comma operator in c
(1 answer)
Not able to understand the reason for output
(3 answers)
Closed 8 years ago.
#include<stdio.h>
int main()
{
int x=10,y=12;
printf("%d",(x,y));
return 0;
}
The output of the program is 12. How?
The expression that you are evaluating is:
x,y
This expression uses the comma operator. The standard (6.5.17 Comma operator) says:
The left operand of a comma operator is evaluated as a void expression; there is a
sequence point between its evaluation and that of the right operand. Then the right
operand is evaluated; the result has its type and value.
So, in your code, x,y evaluates to y, which has a value of 12.
For a more expansive discussion, I refer you to cppreference.com. Although that discusses C++, the discussion for this operator is valid in the context of C. Particularly relevant to your question is this section:
The comma in various comma-separated lists, such as function argument lists (f(a, b, c)), initializer lists int a[] = {1,2,3}, or initialization statements (int i, j;) is not the comma operator. If the comma operator needs to be used in that context, it has to be parenthesized: f(a, (n++, n+b), c).
And that's exactly the situation in your question. If you had written:
printf("%d", x, y);
then there would have been no use of the comma operator, and you would have supplied one more argument to printf than format specifier.
You're by chance using the comma operator.
In the C and C++ programming languages, the comma operator (represented by the token ,) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type).
That said,
printf("%d",(x,y));
is functionally equivalent to
printf("%d", y);
it is because first (x,y) is evaluated.
inside () the expression is x,y they are evaluated from left to right since the Associativity of Comma operator is left to right, so the last value of evaluating (x,y) is y.
read operator precedence and associativity rule and how expressions are evaluated under operator precedence to understand these type of expressions

Variable definition in C

What does following declaration mean in C?
char a = (10,23,21);
While printing the value of "a" with "%u" the output is 21.
gcc is not giving any error.
What's this kinda declaration and what's the use of it?
You are seeing the comma operator at work. The comma operator a,b evaluates a, throws away the result, then returns b.
Since 10 and 23 have no side effects, this is equivalent to char a = 21;
This is a use of the scalar comma operator. The comma operator evaluates each expression on the left side and throws away the return value, finally returning the rightmost value.
In this case, it's useless; however, if you use it with expressions with side-effects, then it has a real effect.
Example of a semi-"useful" expression (with side-effects):
int a = 10;
int is_a_odd_after_increment = ++a, a % 2;
The first expression (++a) has a clear side-effect, and it is evaluated first (before the a % 2). The second expression is the expression that is yielded into the assignment.

Resources