12

I came across unexpected (to me at least) C++ behavior today, shown by the following snippit:

#include <iostream>

int main()
{
  std::cout << ("1", "2") << std::endl;

  return 0;
}

Output:

2

This works with any number of strings between the parentheses. Tested on the visual studio 2010 compiler as well as on codepad.

I'm wondering why this compiles in the first place, what is the use of this 'feature'?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Adversus
  • 2,166
  • 20
  • 23
  • 8
    c++ has a comma operator http://stackoverflow.com/questions/54142/c-comma-operator – bazz Aug 10 '12 at 09:41
  • Figured it would be a duplicate, it didn't occur to me to search for a comma operator. Thanks for all the answers anyway! – Adversus Aug 10 '12 at 20:51

5 Answers5

15

Ahh, this is the comma operator. When you use a comma and two (or more) expressions, what happens is that all expressions are executed, and the result as a whole is the result of the last expression. That is why you get "2" as a result of this. See here for a bigger explanation.

Lyubomir Vasilev
  • 3,000
  • 17
  • 24
8

It's called the comma operator: in an expression x, y, the compiler first evaluates x (including all side effects), then y; the results of the expression are the results of y.

In the expression you cite, it has absolutely no use; the first string is simply ignored. If the first expression has side effects, however, it could be useful. (Mostly for obfuscation, in my opinion, and it's best avoided.)

Note too that this only works when the comma is an operator. If it can be anything else (e.g. punctuation separating the arguments of a function), it is. So:

f( 1, 2 );      //  Call f with two arguments, 1 and 2
f( (1, 2) );    //  Call f with one argument, 2

(See. I told you it was good for obfuscation.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • "Mostly for obfuscation, in my opinion, and it's best avoided" - a classic and reasonable use is to modify multiple variables in `for` loops, e.g. `for (; x > y; x--, y++) ...` – Tony Delroy Aug 10 '12 at 12:53
  • 1
    @TonyDelroy I did say _mostly_. I'm not sure that I wouldn't prefer a `while` loop in the case you site, but it's certainly a case where it is arguably acceptable. The other "widespread" use is in macros, where it can be used to make two statements appear as a single function call, or to "coerce" a void function (e.g. `abort` to a given type, so that it can be used in a ternary operator. – James Kanze Aug 10 '12 at 13:57
3

Comma operator ( , ) The comma operator (,) is used to separate two or more expressions that are included where only one expression is expected. When the set of expressions has to be evaluated for a value, only the rightmost expression is considered.

For example, the following code:

a = (b=3, b+2);

Ref:http://www.cplusplus.com/doc/tutorial/operators/

Lwin Htoo Ko
  • 2,326
  • 4
  • 26
  • 38
  • 1
    Crucially, the comma operator introduces a sequence point, ensuring that each of the expressions from left to right are executed in order, so `b=3` will definitely have executed before `b+2` begins (at least from the perspective of observable behaviour). – Tony Delroy Aug 10 '12 at 09:47
  • exactly. in this case, a = 5, b = 3. – Lwin Htoo Ko Aug 10 '12 at 09:58
1

The result of the comma (",") is the right subexpression. I use it in loops over stl containers:

for( list<int>::iterator = mylist.begin(), it_end = mylist.end(); it != it_end; ++it )
  ...
Alexander Chertov
  • 2,070
  • 13
  • 16
  • 1
    Except that there's no comma operator in your example. – James Kanze Aug 10 '12 at 09:47
  • @JamesKanze I think he's missing the variable name after the first iterator declaration and the type declaration for `it_end`, but they are separated by a comma... – Mihai Todor Aug 10 '12 at 09:50
  • 1
    They are indeed separated by a comma, but I think James meant that this comma is not "operator comma" but it's rather part of a variable declaration list. James, thanks for pointing it out, I will read about it. – Alexander Chertov Aug 10 '12 at 09:59
  • 2
    @AlexanderChertov Exactly. Most commas are not operators, but part of the general syntax. The difference is very important; if you overload the comma operator, the overload will only be taken into account in contexts where the comma actually is an operator. (Not that overloading the comma operator is a good idea, unless your goal is obfuscation.) – James Kanze Aug 10 '12 at 10:07
0

The comma operator evaluates the expressions on both sides of the comma, but returns the result of the second.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621