void main()
int a,b,c;
c=(a,b)
This gives c=b while
c=a,b
gives c=a.
What is the reason for the above two?
In this line:
c=(a,b)
The parentheses mean, "evaluate the expression a,b first, then assign the value to c." In this case, b is assigned, because it's the right-hand-side expression of a,b. In C, comma expressions are evaluated left-to-right, with the overall value being that of the rightmost expression.
While in this line:
c=a,b
The assignment is evaluated as the entire left hand side first, which is c=a. This is because the equal = operator takes precedence over the comma , operator. Thus, b doesn't get assigned to c at all. It is equivalent to:
(c=a),b
In C, the comma operator evaluates the first operand, then discard it and then evaluates the right operand. So the outcome is the right operand. And it has the lowest precedence.
c = (a,b)
() has higher precedence than, so a,b evaluates first. The result is b. So c = b.
But when used c = a,b assignment = have higher precedence. So c = a evaluates first. Thus a is assigned to c.
Check this for further details.
Related
Associativity of conditional operator is from right to left so the right most conditional operator should be solved(testing whether a is true or not) first but the book mentions that first x will be tested
The fact that the conditional operator associates to the right means that x?y:a?b:c will be parsed as if it had been written x?y:(a?b:c). If it associated to the left, it would have been parsed as (x?y:a)?b:c, which would almost certainly have been a surprise (unless you are used to PHP).
But neither of these parentheses change execution order. The conditional operator's first operand is always evaluated first.
The expression
int result = x?y:a?b:c;
can be written as
int result;
if (x)
{
result = y;
}
else
{
if (a)
{
result = b;
}
else
{
result = c;
}
}
So x must be evaluated first to determine whether the if block or the else block will be executed.
Note that the ternary operator only evaluates the expression that it needs to. When x is true, y is evaluated. When x is false, the subexpression a?b:c is evaluated.
In fact, the C standard requires that the code only evaluate the expression that's needed. Here's what it says in section 6.5.15/p4:
The first operand is evaluated; there is a sequence point between its
evaluation and the evaluation of the second or third operand
(whichever is evaluated). The second operand is evaluated only if the
first compares unequal to 0; the third operand is evaluated only if
the first compares equal to 0; the result is the value of the second
or third operand (whichever is evaluated), converted to the type
described below.
In the expression x?y:a?b:c,
the first operand is x
the second operand is y
the third operand is a?b:c
So the standard expressly forbids the code from evaluating any part of a?b:c unless x compares equal to 0.
The associativity only determines how the operands are interpreted. The first, second, and third operands listed above are based on right-to-left associativity.
If the associativity of the ternary operator was left-to-right, then
the first operand would be x?y:a
the second operand would be b
the third operand would be c
Why is the postfix increment operator (++) executed after the assignment (=) operator in the following example? According to the precedence/priority lists for operators ++ has higher priority than = and should therefore be executed first.
int a,b;
b = 2;
a = b++;
printf("%d\n",a);
will output a = 2.
PS: I know the difference between ++b and b++ in principle, but just looking at the operator priorities these precende list tells us something different, namely that ++ should be executed before =
++ is evaluated first. It is post-increment, meaning it evaluates to the value stored and then increments. Any operator on the right side of an assignment expression (except for the comma operator) is evaluated before the assignment itself.
It is. It's just that, conceptually at least, ++ happens after the entire expression a = b++ (which is an expression with value a) is evaluated.
Operator precedence and order of evaluation of operands are rather advanced topics in C, because there exists many operators that have their own special cases specified.
Postfix ++ is one such special case, specified by the standard in the following manner (6.5.2.4):
The value computation of the result is sequenced before the side
effect of updating the stored value of the operand.
It means that the compiler will translate the line a = b++; into something like this:
Read the value of b into a CPU register. ("value computation of the result")
Increase b. ("updating the stored value")
Store the CPU register value in a.
This is what makes postfix ++ different from prefix ++.
The increment operators do two things: add +1 to a number and return a value. The difference between post-increment and pre-increment is the order of these two steps. So the increment actually is executed first and the assignment later in any case.
Consider the following snippet:
int a, b, c;
a = (b = 3, c = 4, 5, 6);
It turns out that, after those lines are executed, b has the value 3, c has the value 4. Nothing unexpected so far. But a has value 6. Why is that?
Also, does this have an useful use?
Because the , operator discards all the operands to the left, and since 6 is the rightmost operand, it's the only one which is not discarded.
This is from § 6.5.17 n1570 draft
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.
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.
You can read more here
Whenever you use a separator (i.e. ',') in an assignment statement, it assigns a value that is in the last. For example
int i = (2,3);
// i = 3;
variable i get the value of 3 not 2.
Talking about the associativity of operators in C, I was wondering why there are differences associativities among operators that have the same precedence. for example, postfix increment and postfix decrement have left associativity; while prefix increment and prefix decrement have right associativity. Isn't it simple to have just left or right associativity for all the same precedence operators?
Are there any reasons behind that?
Isn't it simple to have just left or right associativity for all the
same precedence operators?
Yes and it is the case in C. May be you assumed that prefix and postfix have the same precedence which is wrong. Postfix has a higher precedence than prefix!
Also there is another curious case to consider as to why certain operators have certain associativity. From Wiki,
For example, in C, the assignment a = b is an expression that returns
a value (namely, b converted to the type of a) with the side effect of
setting a to this value. An assignment can be performed in the middle
of an expression. (An expression can be made into a statement by
following it with a semicolon; i.e. a = b is an expression but a = b;
is a statement). The right-associativity of the = operator allows
expressions such as a = b = c to be interpreted as a = (b = c),
thereby setting both a and b to the value of c. The alternative (a =
b) = c does not make sense because a = b is not an lvalue.
Binary operators are all left-associative except the assignment operator which is right-associative.
Postfix operators are sometimes (for exemple in K&R 2nd) said to be right-associative but this is to express the idea they have higher precedence than unary operators.
What does this piece of code in C do:
p = (1, 2.1);
What do we know about p?
The comma operator in C is a sequence point which means that the expressions separated by the comma are executed from left to right. The value of the whole expression is the value of the rightmost expression, in your case 2.1, which gets assigned to the variable p.
Since the expressions in your example don’t have side effects, the use of the comma separator here makes no sense whatsoever.
The parentheses on the other hand are important since the assignment operator (=) binds stronger than the comma operator (it has higher precedence) and would get evaluated before the comma operator without the parentheses. The result would thus be p == 1.
It's a mistake. the comma operator is similar to ;. It does the one, then the other. so (1,2.1) evaluates to 2.1
p will be 2.1 (or 2, if p is an int and needs to be truncated...)
all comma seprated expressions will be evaluated from left to right and value of rightmost expression will be returned.
so p will 2.1.