comma operator in while loop [duplicate] - c

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
Guys when I attended a C quiz online, I came across a statement while(s++,6); where s is initialized to zero. I don't know what the while loop will exactly do when there is a comma operator in between. When I ran it on my gcc compiler it ran with no output. But when I changed the while condition as while(1,s++) it returned s value as 1. Can anyone tell me what is happening at that while.

The comma operator evaluates the left side and then throws away the result. The while condition keeps looping for any value other than zero. The first will be an infinite loop; the second will increment s and then stop.
I suspect in this case the comma was a typo and they meant to type a less-than.

From C11 standard §6.5.17:
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.
This means that 1,s++ evaluates 1 (so nothing happens), then it evaluates s++ and returns the result of that expression only.
So that's expression is equivalent to while (s++). If the left-hand side of a comma expression doesn't have any side effects, like in your situation, then you can remove it.

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.

In c, can a switch statement have 2 arguments? [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 6 years ago.
int main()
{
switch(1,2)
{
case 1:printf("1");break;
case 2:printf("2");break;
default: printf("error");break;
}
}
Is this valid in c?
I thought it shouldn't be , but when I compiled it , it shows no error and produces output 2.
Yes, this is valid, because in this case, the , is a comma operator.
Quoting C11, chapter §6.5.17, Comma operator, (emphasis mine)
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.
This (evaluates and) discards the left operand and uses the value of the right (side) one. So, the above statement is basically the same as
switch(2)
Just to elaborate, it does not use two values, as you may have expected something like, switching on either 1 or 2.

Comma-Separated return arguments in C function [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
While completing a C programming test, I was given a question regarding the expected output from a function which seem to return two values. It was structured as follows:
int multi_return_args(void)
{
return (44,66);
}
The question caught me by surprise and inherently thought that if possible the first argument would be passed to the caller.
But after compiling it, the result is 66 instead. After a quick search I couldn't find anything about structuring a return statement like this so was wondering if some could help me.
Why does it behave like this and why?
The comma operator evaluates a series of expressions. The value of the comma group is the value of the last element in the list.
In the example you show the leading constant expression 44 has no effect, but if the expression had a side effect, it would occur. For example,
return printf( "we're done" ), 66;
In this case, the program would print "we're done" and then return 66.
In your code,
return (44,66);
is making (mis)use of the comma operator property. Here, it essentially discards the first (left side) operand of the , operator and returns the value of that of the second one (right operand).
To quote the 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.
In this case, it is same as writing
return 66;
However, FWIW, the left hand side operand is evaluated as a void expression, meaning, if there is any side effect of that evaluation, that will take place as usual, but the result of the whole expression of the statement involving the comma operator will be having the type and the value of the evaluation of the right hand side operand.
This will return 66. There is nothing special about returning (44,66).
(44,66) is an expression that has the value 66 and therefore your function will return 66.
Read more about the comma operator.
Coma operator always returns the value of the rightmost operand when multiple comma operators are used inside an expression.
It will obviously return 66.

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;
}

Resources