

Forgotten C: The comma operator - donmcc
http://mindtribe.com/2011/07/forgotten-c-the-comma-operator/

======
kqr2
This is probably one of the better use cases for the comma operator in C.

[http://stackoverflow.com/questions/52550/what-does-the-
opera...](http://stackoverflow.com/questions/52550/what-does-the-operator-do-
in-c)

    
    
      string s;
      while(read_string(s), s.len() > 5)
      {
       //do something
      }
    

versus

    
    
      string s;
      read_string(s);
      while(s.len() > 5)
      {
       //do something
       read_string(s);
      }

~~~
tedunangst

        for (read_string(s); s.len() > 5; read_string())
    

or just fix the damned read_string function to return the length read.
[nevermind s.len() is unlikely to appear in C.]

~~~
steve-howard
So is class string, so we're really talking about uses for the operator in
C/C++.

I'd say the for version is better if you can declare the variable in the
initialization section (tighter scope), but the while version has you repeat
yourself less if the variable's already there.

------
huhtenberg
Comma is quite useful for compacting cleanup code in abnormal function exits.
E.g. from this:

    
    
      if (...)
      {
        cleanup();
        return -2;
      }
    

to this

    
    
      if (...)
        return cleanup(), -2;
    

Linux kernel uses this pattern in several places. However the best comma use
is, of course, for messing your enemies' code:

    
    
      foo,();

------
antirez
The comma operator is pretty useful in macros:

    
    
        #define something(...) (printf(... some debug message ...),real_something_expression)
        foo = something(...)
    

This way you can create macros returning values and printing debug messages at
the same time.

~~~
koopajah
This is what I was going to post, comma operator is really useful in macro for
example when overriding mutex lock/unlock to call printf before and still keep
the returned value and not change all calls.

------
bobbyi
C++ allows overloading the comma operator. This can be (ab)used to make the
following syntax work for, e.g., initializing a vectorish type:

    
    
        MyType obj = 1, 2, 3;
    

Due to the precedence of operators, this is actually equivalent to

    
    
        ((MyType obj = 1), 2), 3;
    

so as long as the overloaded assignment operator returns an object that the
comma operator mutates and returns, this can be made the have effect of
initializing the declared object to a "list".

This trick is used by Boost Spirit to allow things like (example from
<http://stackoverflow.com/questions/54142/c-comma-operator>)

    
    
        keywords = "and", "or", "not", "xor";

~~~
jerryr
I think that when you overload the comma operator in C++, you change the
nature of the sequence point. I believe you're no longer guaranteed to have
"1, 2, 3" evaluated in that order. In your example, this doesn't matter, but
if it was "f1(), f2(), f3()" and for some reason the sequence of those calls
determined what each returned, you might have a problem. I could be wrong here
though--my C++ is rusty from years of disuse.

~~~
bobbyi
Item #7 in More Effective C++ is to "never overload &&, || or ," because it
changes the order of evaluation (with the boolean logic operators, it changes
because the usual short-circuiting behavior is gone since the second argument
has to be evaluated to pass it as an argument).

------
gue5t
It's also occasionally useful in the construction of #define macros, where
readability is often sacrificed for proper semantics regarding side effects
and part-of-speech.

------
laichzeit0
For those who want to see a serious use of this operator, see
[http://code.google.com/p/cii/source/browse/trunk/include/exc...](http://code.google.com/p/cii/source/browse/trunk/include/except.h)
line 35. This from an exception (try, catch, except macros) library for the C
language. It is from a book called "C interfaces and implementations",
probably one of the best books on good C programming I have ever (and still)
read.

It's special in the fact that it's written by Hanson (who also co-wrote the
LCC compiler, you might have seen ID Software use this compiler) and the book
uses Knuth's Literary Programming technique for the source code in the book ;)

------
cron
Cute way to reverse a string, taken from the K+R:

    
    
        for (i = 0, j = strlen(s)-1; i < j; i++, j--) 
               c = s[i], s[i] = s[j], s[j] = c;

------
makecheck
I find the comma useful in deletion scenarios. For example, rather than just
"free(x)" or "delete x" (after which the variable is undefined and can't be
used anyway), I like to use the comma to add a NULL assignment. So, "free(x),
x = NULL". It doesn't really need to be that way, but it's nice for avoiding
random behavior in case the variable is referenced later; and the chain on one
line makes it unlikely that the 2nd part will be forgotten.

~~~
andrewcooke
why don't you use the semicolon? the comma is only adding something more if
you're using the final value.

~~~
makecheck
It would hardly ever matter, that's true. But I can certainly contrive
something that would require it, such as:

    
    
        if (something) f();
        else delete x, x = NULL;
    

Of course, I don't personally use "else" without a block, so it's just an
example; I'm not suggesting it's a good idea.

------
pyre
In Perl:

    
    
      my ($a) = (8,9) || (20,21);
      print "\$a = $a\n";
    

Gives:

    
    
      $a = 9
    

Due to the comma operator.

------
Zakharov
The problem with having read_string return the length is that you have to
write

    
    
      while (read_string(s) > 5) // loop until the string length is greater than 5
    

because it's not intuitive that read_string will return the length of the
string. You don't save anything this way.

~~~
rat
Have read_str return const char *

while (strlen(read_string(s)) > 5)

------
catch23
also one the lesser used operator in javascript too.

------
roinsh
The comma in the for loop is quite common, it is actually on the Indian Hill
coding style and standard.

------
ristretto
Could even be used with lvalues

    
    
       (++k, ++k, k) += 100;
    

(works with gcc 3.4)

~~~
xyzzyz
Is the behaviour defined in this case? If so, what does it do?

~~~
mkelly
Because the comma adds a sequence point, it should be defined: the post-
increments both happen before the use of the k lval.

