The Comma Operator in C++

The comma operatorWhen we think of the comma character we often think of it as a separator. It separates values in an CSV file, it separates items in lists, it may separate index values in multidimensional arrays (in other languages) and more. But in C++ an obscure way of using them was as an operator. The reason it never made it big as an operator and into the typical programming psyche is that largely it is seen as useless or some kind of “syntactic sugar”. So in this article we try to show how it works, why it has a stigma and some possible uses for it that may prove useful at some point in your career going forward. Worst case scenario it provides fodder for your geek parties and may even snag you that lady you have had your eye on for awhile.

How does this darn thing work?

The straight forward to think of it is as an operator that has two operands. Much like + or / or * would have in some kind of arithmetic. The two operands are evaluated but the second one is the only one that is actually assigned. Here is an example…

// i is assigned the value 7.
int i = (5,7);

The above code assigns the value 7 to the variable “i”. It sees the left operand (in this case 5) and evaluates it, but its result is thrown away. It then evaluates the right operand and its value is used to complete the assignment. Ok, what is this twisted and demented C++ voodoo all about? Why would anyone want to put in the work of having a left hand operator that has its value thrown away when they really want the operand on the right? This is the first question usually asked and it is perfectly reasonable to think that. This is the stigma that usually follows this operator. The second thing you might be thinking is what is with the parenthesis here? They simply serve to support operator precedence. That is, the assignment operator has greater precedence than the comma operator. If we didn’t have the parenthesis we would have int i = 5,7; and the 5 would be assigned to “i” and then you would get some syntax error for having this ,7 hanging off of it. Chain this comma operator together with others and it will work as expected, yielding the last result… int i = (5, 6, 7); // i is now 7. Here 5 and 6 are evaluated, 6 is returned, it is evaluated with 7 and then 7 is assigned to “i”.

What good is it then?

Well it has a few edge cases that involve things like brevity of if statements (which will show in a second) and also the use of side effects. Generally side effects are bad in programming. We don’t want our code to go doing things we didn’t initially intend them to do. To show you one way this may work is to use our increment operator as seen below…

int a = 3;
int b = 4;

// i will be assigned 4, but "a" was incremented and now is 4.
int i = (a++,b);

Taking this one step further what if the second operand uses the first one? We want the second to evaluate to a result and use the operand from the first, but only after we did something to it.

int a = 3;
int b = 4;

// i will be assigned 8. "a" was still changed permanently.
// "a" was incremented, then the second value was evaluated with the new value of "a" being used.
int i = (a++,a + b);

If you think about it a little bit you can see this same thing can be accomplished in two statements. First increment “a” and then assign i to the value of a + b. From a programming best practice I always advise against this sort of syntax if it even can be remotely considered confusing. Why make things more difficult for others to maintain your code?

Can we use this elsewhere?

Sure, this can be used right in condition statements for loops or if statements etc. Let’s throw it into a while loop and an if statement see what we get…

int a = 0;
int b = 4;

while (a++,b < 10) {
   b += 1;

// a will end up being 7 while b will be 10.
cout << "a is: " << a << " and b is: " << b << endl;

// a is now 3 and since 2 is less than 3, it will print the statements.
if (a = 3,2 < a) {
   cout << "a is: " << a << endl;

// After the if statement, a is still going to be 3.

Our last example is going to show you how this might be used to shorten up a code block and get rid of the need for some curly braces. The example below shows how we can assign to values to variables in a single line and since it is a single line we use it in an if without the need for curly braces.

int a = 0;
int b = 7;

// Single line if statement doing two assignments
if (a == 0) a = 2, b=4;

// Here "a" will now be 2 and "b" will be 4.
cout << "a is: " << a << " and b is: " << b << endl;

It is things like this that make C++ such a fascinating language to play with. My hopes is that next time you see a comma you don’t take it for granted just as something that separates items, but that it can be an operator in its own right. However, just because you can use it this way doesn’t mean you should except for the special cases where it can really help. Out of all my years programming with C++ I never really truly found a solid reason to use it. Sure it can save a few characters or lines but I often prefer to be explicit when I can. The main goal that we all should strive for besides solution correctness is that we also provide solutions that are easy to read, understand and maintain. I find that is often best done using separate statements or assignments.

Thanks for reading! :)

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 17 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.
  • Mark Saleski

    hey there, i tried to add a comment on this over at dreamincode but the comment link took me nowhere and showed now comment box. anyway…

    i’ve been programming in c++ for over 20 years and have used the comma operator once. we had a set of objects that held database data. using an overloaded bracket opererator AND an overloaded comma operator (yes, this isn’t for beginners) we were able do traverse table data. this worked because the database had a particular type of field that they called a “db address,” which was essential a pointer to another table. so with each column having a defined enumeration, you had the ability to just from one row of data to a table that one of its fields pointed to, and to another, etc.

    like this:


    it was a pretty powerful usage, though not one i’d recommend for the inexperienced.


    • Martyr2

      Wow! An awesome real world usage of it. I am sure that is going to help someone out down the road. Thanks for sharing. I have been doing C++ for awhile and I have to admit I have never really needed to use it much myself. Glad to see someone who has found a real world case for it and that it does see some love. :)

      • SeriusSoft

        gotta love the fact that you can create and overload operators in c++ :)
        There are some fun memories of doing this in BigNumber classes and the likes.

  • SeriusSoft

    BTW, I really liked that example used in the while loop. I’ve often found that using commas in an intense for loop was helpful when trying to set a few different indexes at the start or just when instantiating a few throw-away variables in quick scripts to test an idea out.

    One interesting note, though was to one of the first blocks of code you showed:

    int a=3;
    int b=4;
    int i = (a++,a+b);

    in this instance, you mentioned that it was similar to doing:
    a++; //or a+=1;
    int i = (a+b);

    you could also still maintain 1 line of code (where it makes it more readable) by doing:

    //because the ++a returns the value of a+1 while storing it,
    // and then that incremented value was then added to b to store into i
    int i = (++a + b);

    (man, I’m just putting off sleep by reading these articles, but I think I should share this one with a fellow developer who is looking at jobs that require c++ as he might get a kick out of this reminder :) )