Hi, I am learning the comma operator, and I am going through a problem which uses it, but I am having an issue with it. I have put the code from the problem below. I am just unsure why i turns out to be 1010 and not 1110. I figure the 100, from the j+100 does not get added to the j, but I do not understand why this is? Could someone please explain why?
1 2 3 4 5 6
int i, j;
j = 10;
i = (j++, j + 100, 999 + j);
cout << i;
> (j++, j + 100, 999 + j);
¿is the order of evaluation specified?
¿may 1009 be a valid answer?
¿undefined behaviour?
¿will be everybody in your team answer those questions at once in two months?
OK I think I am understanding it now, the second part is just basically 11 + 100 and nothing is happening with it, then i is being assigned the last part, 999 + j. The break down you gave really helped, so thank you for that.
Also, the book I am learning from is somewhat old, 2003 I believe. I take it from your comments xD the comma operator is no longer standard?
its still standard, its just less than useful. Not only is it not necessary, but it often leads to misleading code that will trip up even a fairly competent c++ coder due to infrequency of use and just the way the syntax looks.
It's fine to use the comma operator. Just because it's uncommon doesn't mean it isn't useful. For example: while (doSomePrep, test condition) ...
Let's look at your expression: i = (j++, j + 100, 999 + j);
Code like this raises all sorts of red flags for C and C++ developers. The reason is that for most operators, the operands are evaluated in an unspecified order. So for example, if we change , to + and + to * we get: i = (j++ + j*100 + 999*j)
and this expression is undefined. The reason is that the compiler may evaluate j++, j*100 and 999*j in any order, or even in parallel. The value would be different, depending on when j++ was evaluated.
Repeat after me: operands are evaluated in an undefined order.
Now that's almost always true, but there are a few exceptions: the &&, || and , operators evaluate the left operand first. && and || also evaluate the right operand only if necessary, but that's not relevant here.
So the red flags turn green because , is unusual. Its operands are evaluated in a specified order.
I take it from your comments xD the comma operator is no longer standard?
The comma operator is still in the standard. It still works. It's just rarely used and when it is everyone who never uses it sits around asking if the order of evaluation is specified and wondering why the writer wrote it that way. Code is written not just for the compiler; it's written also for humans to read. If you write something that you know readers will struggle to understand, you've written bad code. Sometimes you have no option. Sometimes you really, really do.
In my experience, beginners like strong, simple guidelines that are helpful and appropriate in the vast majority of cases, and in almost everything a beginner will do. Things like "don't use new, don't use delete" and "don't put 'using namespace std;' at the top of everything you write". I would suggest that "don't use comma operator" goes alongside those.
Comma operator expressions are evaluated strictly left to right with the value of the entire expression being the value of the right-most expression (the one evaluated last). It is often used in for () statements to cause a sequence of operations to be performed as part of the for - rather than within the for body.
Also note that using , to define multiple variables is NOT the comma operator. So
int a,b,c;
is not using the comma operator.
Also, there is a 'well-known' gotcha when used with the ternary operator. Consider:
1 2 3 4 5 6 7 8 9
bool a = true;
bool b = false;
int i;
i = a ? 1, 2 : 3, 4;
cout << i << endl;
i = b ? 1, 2 : 3, 4;
cout << i << endl;
what values are displayed?
[take a second to think about it]...
The answer is
1 2
2
3
The reason that 3 is displayed and not 4 is that the statement is evaluated as
i = (b ? 1, 2 : 3), 4;
because of operator precedence.
OK, but why is i not always 4? Because it is evaluated as:
(i = (b ? 1, 2 : 3)), 4;
so the 4 is not used! , is the lowest precedence operator. Every other operator has a higher precedence and is evaluated before ,
If you write something that you know readers will struggle to understand, you've written bad code.
It's definitely true that simple code is better than complex code, but if the code needs to be complex, then you can make it clearer by adding a comment to explain what's going on.
Basically I think code should be as simple and clear as possible, but no simpler. Don't dumb down the code unnecessarily.
FG - the oldest and most incompetent sniper on this forum. Forever telling everybody homilies that amount to nothing - an educational backgound in programming best described as 'void'.
FG - the oldest and most incompetent sniper on this forum. Forever telling everybody homilies that amount to nothing - an educational backgound in programming best described as 'void'.
Hmm. The sample program above has an 'obvious' flaw in that a double is subtracted from an int giving an int......
That 'obvious flaw' was intended, that is why I said a bit hackish. To not subtract merely 8 with every loop iteration, while still yielding an integer result each time.
Leveraging integer math conversions..... If that is incompetence, so be it.
The same output result could have been achieved with subtracting 9, but it wouldn't have been as 'hackish.'
Now we can add incoherence to the incompetence. As a face-saving attempt that explanation, or whatever it is supposed to be, goes beyond doubling down or digging the hole deeper, is an entire excavation bigger than the Mariana Trench.