Home > C, Programming Languages > C loops: for() and the comma operator

C loops: for() and the comma operator

Everybody knows that in C a for loop has the syntax:

for (variable initialization; exit condition; variable update) {
++++// the body comes here
}

a typical example being:

int i;
for (i = 0; i < 5; i++) {
++++printf("%i ", i);
}

However, all three expressions in the for statement are optional. Even the body is optional. Due to this flexibility when one starts to read C code written by other people it is easy to find for loops with very different looks. In general, those variations are easy to understand. For instance, the above loop can also be written as follows:

int i = 0;
for(; i < 5; i++) {
++++printf("%i ", i);
}

so the variable initialization has been done before the loop is called. If the exit condition is absent then it always evaluates to True. And if the update variable expression is omitted then it is done in the loop body. If all three expressions have been removed from the for statement then we have a potentially infinite loop and we should insert a break statement somewhere in the body.

Things get interesting when the for statement is combined with the infrequently used comma operator.

The comma operator is a sequence point (as they are && and ||) so the order of evaluation of the operands is fixed. It is a binary operator that evaluates its first operand, performs all side effects and discards the result, and then evaluates the second operand and returns its value and type so:

x = (y, z);

will do y and, after performing all side effects, will discard it, then do z and finally will set x to z.

Because the comma operator discards its first operand, it is useful where the first operand has desirable side effects, such as in the initializer or the counting expression of a for loop.

We can use that operator to combine the variable update and the exit condition expressions of the for statement in a single expression:

int i=-1;
for (;i=i+1,i<5;) {
++++printf("%i ", i);
}

As a result, at each iteration the counter is incremented and discarded, then exit condition is evaluated and its result returned so the value of the comma expression is the value of the exit condition.

The equivalent while loop is:

int i=-1;
i = i + 1;
while(i < 5) {
++++printf("%i ", i);
++++i = i + 1;
}

In the following example the exit condition works as in the previous one. In addition, two variables are set in the variable initialization expression. And the update variable expression is used to append statements to the body of the loop:

int i, j;
for (i=-1,j=0;i=i+1,i<5;j=i+1,printf("%i\n", j)){
++++printf("%i\t", i);
}

It is equivalent to the following while loop:

int i = -1;
int j = 0;
i = i + 1;
while(i<5) {
++++printf("%i\t", i);
++++j = i + 1;
++++printf("%i\n", j);
++++i = i + 1;
}

Notice that the examples above are intentionally simple. They just pretend to show you how the combination for statement + comma operator works. In general, comma operator is used to produce side effects in the following situations:

  • calling a function
  • entering or repeating an iteration loop
  • testing a condition

You can see also:

  1. Scott
    November 14, 2012 at 5:55 pm

    Very nice summary. Are there programmatic or performance reasons why one might choose one form over another? It seems that from a code maintainability point-of-view, it might be preferable to stick with the classic “for (variable initialization; exit condition; variable update)” form.

    • November 17, 2012 at 5:54 pm

      AFAIK there are no performance improvements when using the comma operator. From a usability point of view I think that using it is just a matter of taste (as it happens, for instance, with short-circuit operators). Some programmers consider the comma operator a way of writing convoluted code. However, other developers like the possibility of writing concise code instead of verbose one in situations such as entering a repeating loop or testing a condition. If you understand how it works and you find a case in which using it can be an advantage (instead of just syntactic sugar) then I don’t see any problem on using the comma operator.

  1. No trackbacks yet.

Leave a comment