If you see this code,
class A{
public:
A(int a):var(a){}
int var;
};
int f(A obj) {
return obj.var;
}
int main() {
//std::cout<
This has to do with the language definition of expressions, which is quite complex.
f(1, 2)
is a function call expression with two parameters. Contrarily, f((1, 2))
is a function call expression with one parameter, which is the sub-expression 1, 2
, which will evaluate to 2.
The use of the comma token as an operator is distinct from its use in function calls and definitions, variable declarations, enum declarations, and similar constructs, where it acts as a separator.
Wikipedia - Comma operator
I did a search over the draft Standard. Basically, in the grammar the -list
productions are the ones that have commas in them to separate different items. The following results are C++03 specific. In C++0x, expression-list directly delegates to initializer-list because in C++0x brace lists can occur in function and constructor arguments likewise.
init-declarator-list The different names declared in one declaration
Example:
int a, b;
member-declarator-list Similar to the init declarator list, but for member declarations in classes.
Example:
struct A { int a, b; };
mem-initializer-list List of the initializers for members
Example:
struct A { A():a(0), b(0) { } int a; int b; };
type-id-list List of types for exception specifications
Example:
void f() throw(int, bool) { }
There is an identifier-list for macro parameters too, which i haven't got in that list because it's really part of the preprocessor grammar.
A comma operator always acts as a comma operator, but a comma doesn't always signify a comma operator -- sometimes it's just punctuation.
As to when it's punctuation, the simple answer is "when the standard says so." Going through all the situations where the standard says so gives a much longer answer -- but one that's unlikely to be much more useful, because (for one example) it has to deal with a number of corner cases most people don't care much about.
From a grammatical point of view, the parameters of a function call form an optional expression-list inside parentheses. An expression-list consists of one or more assignment-expression separated by a comma token. A comma can only signify a comma operator where an expression is expected.
The comma operator makes an expression out of an expression, a ,
and an assignment-expression, but an expression involving a comma operator is not itself an assignment-expression so can't appear in an expression-list except where it's a constituent of something that is an assignment-expression.
For example, you can surround any expression (including one using the comma operator) inside parentheses to from a primary-expression which is an assignment-expression and hence valid in an expression-list.
E.g.
postfix-expression where the expression-list consists of two assignment-expression each of which is an identifier.
f( a, b );
postfix-expression where the expression-list consists of a single assignment-expression which is a primary-expression which is a parenthesized expression using the comma operator.
f( (a, b) );