comma operator

Sep 1, 2020 at 8:32pm
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;
Sep 1, 2020 at 8:40pm
Do not use the comma operator.

Do not use the comma operator.

Do not use the comma operator.

Now that that's been said, your code is similar to this.

1
2
3
4
5
6
7
8
int i, j;
j = 10;

j++; // J IS NOW 11
j + 100; // THIS DOES NOTHING
i = 999 + j; // J IS STILL 11, i IS 999 + 11 

cout << i;


i is set to 1010 because 999 + 11 = 1010.

Do you see the difference between these two lines of code?
1
2
j + 100
j = j + 100

Do you see how
j + 100
does not change the value of j?

Do not use the comma operator.

Do not use the comma operator.

Do not use the comma operator.

Last edited on Sep 1, 2020 at 8:41pm
Sep 1, 2020 at 9:14pm
> (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?
Sep 1, 2020 at 9:22pm
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?
Sep 1, 2020 at 11:19pm
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.

Sep 1, 2020 at 11:25pm
The behavior is standard (C++17 also made user-defined comma operator have the same sequence points, so it is OK to say (j++, j) in the comma operator), but yeah what jonnin said.
https://en.cppreference.com/w/cpp/language/operator_other#Built-in_comma_operator
Last edited on Sep 1, 2020 at 11:27pm
Sep 2, 2020 at 3:05am
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.
Sep 2, 2020 at 8:10am
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.
Last edited on Sep 2, 2020 at 8:14am
Sep 2, 2020 at 9:38am
operands are evaluated in an undefined order.


This was somewhat tightened in C++17 with P0145 (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf)

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 ,

Also see https://www.fluentcpp.com/2018/07/31/how-to-get-along-with-the-comma-operator/
Sep 2, 2020 at 2:09pm
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.
Sep 3, 2020 at 10:43pm
I personally can think of one use of the comma operator, in a for loop. Defining and manipulating two (or more) variables.

IMO a bit on the hackish side, but the operator does have a (somewhat) use:
1
2
3
4
5
6
7
8
9
#include <iostream>

int main()
{
   for (int i { }, j { 123 }; i < 10; i++, j -= 8.5)
   {
      std::cout << i << ' ' << j << '\n';
   }
}
0 123
1 114
2 105
3 96
4 87
5 78
6 69
7 60
8 51
9 42

There are a number of features C++ has I don't use that much, the comma operator is one.
Sep 4, 2020 at 12:32pm
There are a number of features C++ has I don't use ...
From what I've seen over many months, in FG's case that would be most features. that's the longest 'program' I've seen FG post here.
Sep 4, 2020 at 1:10pm
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'.
Sep 4, 2020 at 1:21pm
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......
Sep 4, 2020 at 2:43pm
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.'
Sep 4, 2020 at 5:41pm
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.
Topic archived. No new replies allowed.