Archive

Archive for November, 2012

C loops: for() and the comma operator

November 2, 2012 2 comments

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:

Advertisement