{{Short description|Programming languages binary operator}} In the C and C++ programming languages, the '''comma operator''' (represented by the token <code>,</code>) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type). There is a sequence point between these evaluations.
The use of the comma token as an {{em|operator}} is distinct from its use in function calls and definitions, variable declarations, enum declarations, and similar constructs, where it acts as a {{em|separator}}.
==Syntax== The comma operator separates ''expressions'' (which have value) in a way analogous to how the semicolon terminates ''statements,'' and sequences of expressions are enclosed in parentheses analogously to how sequences of statements are enclosed in braces:<ref name = "Various, Microsoft, 2019" >{{ Cite web | url = https://docs.microsoft.com/en-us/cpp/cpp/comma-operator?view=vs-2019 | title = Comma Operator | access-date = 1 August 2019 | website = Microsoft dev docs | quote = Two expressions separated by a comma are evaluated left to right. The left operand is always evaluated, and all side effects are completed before the right operand is evaluated. | archive-url = https://web.archive.org/web/20190802022035/https://docs.microsoft.com/en-us/cpp/cpp/comma-operator?view=vs-2019 | archive-date = 2 August 2019 | df = dmy-all }}</ref> <code>(a, b, c)</code> is a sequence of expressions, separated by commas, which evaluates to the last expression <code>c</code>, while <code>{a; b; c;}</code> is a sequence of statements, and does not evaluate to any value. A comma can only occur between two expressions – commas ''separate'' expressions – unlike the semicolon, which occurs at the end of a (non-block) statement – semicolons ''terminate'' statements.
The comma operator has the lowest precedence of any C operator, and acts as a sequence point. In a combination of commas and semicolons, semicolons have lower precedence than commas, as semicolons separate statements but commas occur within statements, which accords with their use as ordinary punctuation: <code>a, b; c, d</code> is grouped as <code>(a, b); (c, d)</code> because these are two separate statements.
As of C++20, the comma operator has been deprecated in subscripting expressions, to reduce confusion, and open up the future possibility of repurposing the syntax for multidimensional array indexing.<ref>{{Cite web |title=P1161R2: Deprecate uses of the comma operator in subscripting expressions |url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1161r2.html |access-date=2022-09-05 |website=www.open-std.org}}</ref> In C++23, the ability to overload <code>operator[]</code> with multiple arguments was added making unparenthesised comma expressions unusable in subscripts.<ref>{{Cite web|url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2128r6.pdf|title=Multidimensional subscript operator|date=2021-09-14|author1=Mark Hoemmen|author2=Daisy Hollman|author3=Corentin Jabot|author4=Isabella Muerte|author5=Christian Trott}}</ref> The comma operator is still usable and not deprecated in this context if the comma expression is surrounded by parentheses (as in <code>a[(b,c)]</code>).
==Examples== {| class="wikitable" |- ! style="width: 220px;" | Example !! {{verth|Return value}} !! Behavior |- |<syntaxhighlight lang="c"> int a = 1, b = 2; int r = (a, b); return r; </syntaxhighlight> | 2 || During initialization the comma acts as a separator, but in the second line it is an operator. The parentheses are required. Without them the second line would be equivalent to {{code|2=c|1=int r = a; int b}}, which results in {{mono|b}} being defined twice, which is illegal. |- |<syntaxhighlight lang="c"> int a = 1, b = 2; int r = (a += 2, a + b); return r; </syntaxhighlight> | 5 || since {{code|2=c|1=a += 2}} is evaluated before {{code|2=c|a + b}} is evaluated and assigned to {{mono|r}}. |- |<syntaxhighlight lang="c"> return(1, 2); </syntaxhighlight> | 2 || The comma is an operator, not a separator, since {{code|2=c|return}} is a keyword and does not act as a function. |}
==Uses== The comma operator has relatively limited use cases. Because it discards its first operand, it is generally only useful where the first operand has desirable side effects that must be ''sequenced before'' the second operand. Further, because it is rarely used outside of specific idioms, and easily mistaken with other commas or the semicolon, it is potentially confusing and error-prone. Nevertheless, there are certain circumstances where it is commonly used, notably in for loops and in SFINAE.<ref>{{cite web|url=https://en.cppreference.com/w/cpp/language/sfinae|title=SFINAE|website=en.cppreference.com|access-date=2022-08-30}}</ref> For embedded systems which may have limited debugging capabilities, the comma operator can be used in combination with a macro to seamlessly override a function call, to insert code just before the function call.
===For loops=== The comma operator allows multiple assignment statements without using a block statement, for example in the initialization and the increment expressions of a for loop. In the following example, the order of the loop's initializers is significant: <syntaxhighlight lang="C"> void rev(char *s, size_t len) { char *first; for (first = s, s += len; s >= first; --s) { putchar(*s); } } </syntaxhighlight>
An alternative solution to this problem in other languages is parallel assignment, which allows multiple assignments to occur within a single statement, and also uses a comma, though with different syntax and semantics. This is used in Go in its analogous for loop.<ref>[http://golang.org/doc/effective_go.html Effective Go]: [http://golang.org/doc/effective_go.html#for for], "Finally, Go has no comma operator and ++ and -- are statements not expressions. Thus if you want to run multiple variables in a for you should use parallel assignment (although that precludes ++ and --)."</ref>
===Macros=== The comma can be used in preprocessor macros to perform multiple operations in the space of a single syntactic expression.
One common use is to provide custom error messages in failed assertions. This is done by passing a parenthesized expression list to the <code>assert</code> macro, where the first expression is an error string and the second expression is the condition being asserted. The <code>assert</code> macro outputs its argument verbatim on an assertion failure. The following is an example:
<syntaxhighlight lang="c"> for (int i = 0; i <= 9; i++) { assert(("i is too big!", i <= 4)); printf("i = %i\n", i); } </syntaxhighlight>
===Condition=== The comma can be used within a condition (of an if, while, do while, or for) to allow auxiliary computations, particularly calling a function and using the result, with block scoping: <syntaxhighlight lang="C"> if (y = f(x), y > x) { // statements involving x and y } </syntaxhighlight> A similar idiom exists in Go, where the syntax of the if statement explicitly allows an optional statement.<ref>The Go Programming Language Specification: [http://golang.org/ref/spec#If_statements If statements]</ref>
===Complex return=== The comma can be used in return statements, to assign to a global variable or out parameter (passed by reference). This idiom suggests that the assignments are part of the return, rather than auxiliary assignments in a block that terminates with the actual return. For example, in setting a global error number: <syntaxhighlight lang="C"> if (failure) { return (errno = EINVAL, -1); } </syntaxhighlight>
===Avoid a block=== For brevity, the comma can be used to avoid a block and associated braces, as in: <syntaxhighlight lang="C"> if (x == 1) y = 2, z = 3; </syntaxhighlight>
===Overloading=== C++ allows overloading the comma operator, as both a binary operator and as a non-member.<ref>{{Cite web|title=Other operators|url=https://en.cppreference.com/cpp/language/operator_other|author=cppreference.com|publisher=cppreference.com|website=cppreference.com|access-date=2 May 2026}}</ref> Its signatures are: * <syntaxhighlight lang="cpp" inline>U& T::operator,(U& rhs);</syntaxhighlight> (inside class definition) * <syntaxhighlight lang="cpp" inline>U& operator,(const T& lhs, U& rhs);</syntaxhighlight> (outside class definition)
This allows for DSL-style APIs, like the following: <syntaxhighlight lang="cpp"> Logger logger; logger, "Hello, ", "world!"; </syntaxhighlight>
==Other languages== In the OCaml and Ruby programming languages, the semicolon (";") is used for this purpose.
JavaScript,<ref name="MDN, 2014">{{Cite web | url = https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator | title = Comma operator | access-date = 2020-01-25 | date = 2020-01-17 | website = MDN Web Docs | quote = You can use the comma operator when you want to include multiple expressions in a location that requires a single expression. | archive-url = https://web.archive.org/web/20140712200108/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator | archive-date = 2014-07-12 | df = dmy-all }}</ref> Perl<ref>{{Cite web | url = https://perldoc.perl.org/perlop.html#Comma-Operator | title = Perlop - Perl operators and precedence - Perldoc Browser }}</ref> and D<ref>{{Cite web | url = https://dlang.org/spec/expression.html#comma_expression | title = Expressions - D Programming Language § Comma Expression }}</ref> utilize the comma operator in the same way C/C++ does.
Some other languages with C-like syntax, such as Java<ref>{{Cite web | url = https://stackoverflow.com/questions/38733508/is-comma-operator-or-separator-in-java |title = Is comma (,) operator or separator in Java? }}</ref> and C#, do not have this feature, though C# supports a comma-separated list of expressions in the initializer and iterator of a {{code|for}} statement,<ref>{{Cite web | url = https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#1394-the-for-statement | title = Statements - C# Language Specification {{!}} Microsoft Learn § The for statement }}</ref> thus enabling an equivalent of this in this specific context.
==See also== * {{Annotated link|Operators in C and C++}}
==References== {{reflist}}
===Bibliography=== {{refbegin}} * {{citation|last=Ramajaran|first=V.|title=Computer Programming in C|publisher=Prentice Hall of India|place=New Delhi|year=1994}} * {{citation|last=Dixit|first=J.B|title=Fundamentals of computers and programming in C|publisher=Laxmi Publications|place=New Delhi|year=2005}} * {{citation |last1=Kernighan |first1=Brian W. |last2=Ritchie |first2=Dennis M. |authorlink2=Dennis M. Ritchie |date=1988 |title=The C Programming Language |edition=2nd |publisher=Prentice Hall |place=Englewood Cliffs, NJ}} {{refend}}
==External links== * "[https://stackoverflow.com/questions/2087026/effect-of-using-a-comma-instead-of-a-semi-colon-in-c-and-c Effect of using a comma instead of a semi-colon in C and C++]", ''Stack Overflow'' * [http://www.boost.org/doc/libs/1_44_0/libs/assign/doc/index.html Boost.Assignment] – facility from the Boost library that makes it easy to fill containers by overloading the comma operator
Category:C (programming language) Category:C++ Category:Operators (programming)