About C++ comma operator precedence

Summary

C++ developers frequently encounter surprising behavior when combining the comma operator with the ternary operator (?:) due to their relative precedences. The comma operator has lower precedence than the ternary operator, causing expressions separated by commas to be evaluated outside the conditional scope of the ternary if not explicitly parenthesized. This can lead to parts of an expression executing unconditionally, regardless of the ternary's true or false branch. For example, `condition ? expr1, expr2 : expr3, expr4` effectively groups as `(condition ? expr1, expr2 : expr3), expr4`. To prevent unexpected results and improve code clarity, it is crucial to use parentheses extensively in complex expressions involving these operators.

When learning programming language, we will always have one topic about the operator precedence. Since there are many operators can be used in one expression, there should be some rules regarding which operation can happen first so that the compiler or interpreter can handle them correctly. One rule of programming with expression is using as much as brackets as you can to avoid unexpected results.

Here we refer one problem we see online about the comma operator in C++. The following program has the result which some people may feel strange.

The first code snippet:

01
02
03
04
05
06
07
08
09
10
void main ()
{
    bool test=false;
    int a = 1;
 
    test == true ? printf("hello\t"), printf("world\n"),a++ :
    printf("Ha\t"), a++, a++;
 
    printf("%d", a);
}

When test==false , a=3

When test==true,   a=4;

The second code snippet:

01
02
03
04
05
06
07
08
09
10
void main ()
{
    bool test=false;
    int a = 1;
 
    test == true ? printf("hello\t"), printf("world\n"),a++ :
                         (printf("Ha\t"), a++, a++);
 
    printf("%d", a);
}

When test==false, a=3;

When test==true,  a=2;

Do you know why we have the above output? Actually, the key here is the precedence of comma relative to ?: in C++. In C++, comma(,) has lower precedence than ?:. If you understand this, the above output is expected.

Let's see the explanations.

For the first code snippet: If we add brackets to the statement, it should look like :

(test == true ? printf(“hello\t”), printf(“world\n”),a++ :printf(“Ha\t”)), a++, a++;

So no matter test equals to true or false, the last two a++ will always be executed. Then if test==true, the a++ before the colon(:) will also be executed, the output will be 4. If test == false, then the result will be 3.

For the second code snippet We apply the same bracket. The statement should look like :

(test == true ? printf("hello\t"), printf("world\n"),a++ :(printf("Ha\t"), a++, a++));

If test== true, only the a++ before colon(:) will be executed, so the output will be 2. If test== false, then the last two a++ will be executed, the output will be 3.

Also, the use of comma is to concatenate some expressions, the value of the whole expression is the value of the last expression.

If we have :

test = true;

b = (test == true ? printf(“hello\t”), printf(“world\n”),a++ :printf(“Ha\t”), a++, a++);

printf(“%d,%d”, a,b);

If we remove the bracket :

test = true;

b = test == true ? printf(“hello\t”), printf(“world\n”),a++ :printf(“Ha\t”), a++, a++;

printf(“%d,%d”, a,b);

Then a=4, b=1.

If test==false in above statement:

test = false;

b = test == true ? printf(“hello\t”), printf(“world\n”),a++ :printf(“Ha\t”), a++, a++;

printf(“%d,%d”, a,b);

Then a=3, b=3;

Why, because the return value of printf() is the number of chars printed if it executes successfully, if printf() fails to execute, it will return a negative value.

In conclusion, when writing complex expressions, please remember use brackets as much as you can to keep your logic clear. By doing so, you can avoid the probability of getting unexpected output. It can also improve the readiness of your code and make your code easy to maintain.

Original author : Sigma Reference : http://www.sigma.me/2011/10/16/c-lang-comma-operator.html

COMMA PRECEDENCE

  RELATED

  COMMENT

1
techi
Dec 26, 2012 at 12:49 am
cool artical. i also found gud content on c++ at techighost.com