Consider the code:
int i, j;
i = (i = 1, j = 3);
i++;
cout<<i<<" "<<j;
This printed 4 3 (c++14).
I read that the comma operator evaluates the expression on its left and returns the one on its right. Now if that is correct, I want to know what is the return value of j = 3? Is it the rvalue? Or a reference to the lvalue?
How does this actually work?
I want to know what is the return value of j = 3?
Assignment operations* return (or "evaluate to") a reference to the left-hand side of the operation, in this case j.
So i = (i = 1, j = 3); is identical to:
i = 1;
j = 3;
i = j;
*For built-in types that is. Custom operator= overloads may return whatever they want, although it's recommended to return a reference to *this as it is the expected behavior among C++ programmers.
To calculate (i=1, j=3), it calculates, from left to right, the expressions separated by comma, and returns the value of the last (rightmost) expression. So it calculates i=1 (i becomes 1), then it calculates j=3 (j becomes 3), then returns 3.
After calculating (i=1, j=3), which returned 3, it performs the assignment, which sets i to 3.
Then i++ is calculated, which sets i to 4.
Then i and j are printed.
The assignment operator returns an lvalue referring to the left operand. It groups right-to-left. ([expr.ass]). Note that saying returning a reference to the lvalue doesn't make sense - it either returns an lvalue or not.
The comma operator performs the value computations and side effects from the left operand, discards them, and then does the same for the right operand. ([expr.comma])
So refactoring the comma operator would produce the following equivalent code:
i = 1; // left operand, value discarded
i = j = 3; // right operand, value preserved
i++;
and then refactoring the compound assignment would produce the following still equivalent code:
i = 1;
j = 3; // rightmost assignment
i = j; // leftmost assignment
i++;
Related
so after
#include <stdio.h>
int main(int argc , char *argv[])
{
int n;
n = _strlen_recursion("Corbin Coleman");
printf("%d\n", n);
}
int _strlen_recursion(char *s)
{
static int count = 0;
count++;
return (count), count = 0;
}
where the comma operator is in action
0 can be seen on screen. Why?
So the real question is : does return have () overload as say sizeof does?
return is not similar to sizeof. The operand of sizeof is either a type in parentheses or an expression.
A return statement has only an expression (or nothing). Parentheses are not part of the grammar of a return statement. Parentheses may be present only because they are part of the expression.
In return (count), count = 0;, the expression is (count), count = 0. That is a comma expression. It evaluates (count), discards the resulting value, then evaluates count = 0. The value of that is the value assigned, 0, so that is the value of the comma expression, so 0 is returned.
In the return statement return (count), count = 0;,
attr(optional) return expression(optional) ; (1)
The expression is (count), count = 0, as comma operator, the 1st operand (count) is evaluated and the result is discarded, then the 2nd operand count = 0 is evaluated, its value 0 is returned as the return value of the omma operator, and returned as the return value of _strlen_recursion() later.
The comma acts as a binary operator in C, the same way +, -, &, and all the other operators in C do. It takes two operands and acts as a sequence point. The left operand, (count) in your example, is evaluated, the result is then discarded. From here, the right operand, count = 0, is evaluated and its return value is returned. In your example, the left operand has no side-effects, so it is essentially useless. The line return (count), count = 0; is equivalent to the two lines
(void) (count);
return count = 0;
Note that count = 0 is an assignment, and in C, assignments return the value assigned, so in this case 0 is returned form this expression, and ultimately the function.
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.
My teacher handed me this homework assignment. As a beginner, I'm just not sure at all where to start, or what this chart is even asking for. Can someone explain this all to me simply? The teacher wants us to fill in the type, side-effect (if applicable,) and value:
(http://i172.photobucket.com/albums/w32/Ravela_Smyth/Graph%201_zpslyxjgpde.jpg)
(http://i172.photobucket.com/albums/w32/Ravela_Smyth/Graph%202_zpskoo3upjw.jpg)
Edit: Why do I keep getting flagged down? I don't understand what I did wrong?
It is simple:
Expression, some part of code, which does something, like a + b
Type, it is asking, what is the result type of the expression, that can get tricky in C++ :).
Side-Effects, the statement has result type and result of some sort but expression can in same time update some variables in the process as sife effects.
Here is an example:
int i = 0;
int j = 0;
int k = 1;
auto rslt = cout << ++i << ( j += 2) << (k *= 5);
//now type of rslt would be? => &ostream, because &cout is of type ostream
// and we used overloaded operators for ostream and that overloaded operator
// is always returning ostream
// I hope you know auto, auto is leaving the decision about type on the compiler.
on screen there would be: 125
now side effects:
++i // side effect of the operation is i: 1
(j += 2) // side effect of the operation is j: 2
(k *= 5) // side effect of the operation is k: 5
The value would be cout.
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.