Bendegúz Csirmaz

PHP quiz #1 - for loop

For loops are one of the most fundamental and ubiquitous control flow statements. They are so essential to computer programming, you would expect every developer to know them inside out. As for me, I never would have thought I could learn anything new about them - I was wrong.

Question

What will this code output?

<?php

for ($i = 0, $j = 0; $i < 3, $j < 2; ++$i, ++$j) {
  echo "$i,$j\n";
}
  • A
    Syntax error
  • B
    0,0
    1,1
    2,2
  • C
    0,0
    1,1
  • D
    0,0
    1,1
    2,1

Answer

Show the answer
C
0,0
1,1

Explanation

The for loop header

Similarly to other languages, it is perfectly legal to initialize and update multiple variables in for loop headers. Consider the following:

for ($i = 0, $j = 0; ...; ++$i, ++$j) // OK!

This is a valid PHP code snippet, and it does exactly what you would expect: it introduces two variables, $i and $j, with the initial value of 0, and it increments them by one at the end of each iteration.

No trickery here.

The difficulty lies in the loop's condition:

for (...; $i < 3, $j < 2; ...) // ???

It might not be immediately obvious what effect does this code have on the loop. One thing's for sure: it won't throw any syntax errors, it's syntactically correct.

Surprising as it may seem, $i < 3, $j < 2 is actually a single expression, and as all expressions, it evaluates to something.

Comma operator (C)

In C, the comma operator (,) is an operator that evaluates two expressions and returns the result of the second one.

For example, the following code prints the text Hello World! to stdout, and assigns 3 to variable a:

int a = (printf("Hello World!\n"), 1 + 2);

The paranthesized expression is evaluated something like this:

/* 0. */ printf("Hello World!\n"), 1 + 2
/* 1. */ 13, 3
/* 2. */ 3

Comma operator (PHP)

This ancient operator did not stand the test of time, not many programming languages support it.

PHP doesn't do either. It's not listed in the precedence table and using it will generally result in a syntax error.

<?php

// Parse error: syntax error, unexpected ',' in ...
$a = (1, 2);

However, surprisingly, there is an exception to the rule: for loop conditions.

For some strange reason, in for loop conditions the comma operator is correctly evaluated.

for (...; $i < 3, $j < 2; ...)
for (...; $j < 2; ...)

In this case, the expression $i < 3, $j < 2 has the same effect as $j < 2. The first operand is evaluated, but its result is disregarded.

The loop will only iterate twice.


This post is part of a series based on a presentation I gave at Cheppers on March 20, 2019.