In niek_e's example, the init-expression, cond-expression, and loop-expression are all optional as long as you include the separating semicolons. That's why an infinite "forEVER" loop looks like this:
for (;;) {
...
}
As long as the loop does what you want, the syntax is very flexible. In Ed's experience, the usual culprits are a very long initialization that makes the loop line too long and a more complicated update:
// So long it makes more sense outside the loop
std::vector<std::pair<std::string, double> >::size_type index = 0;
for (; index != v.size(); ++index) {
...
}
// As a part of the loop (too long)
for (std::vector<std::pair<std::string, double> >::size_type index = 0; index != v.size(); ++index) {
...
}
// n isn't incremented with every loop
for (n = 0; n < 10 && std::getline(std::cin, input); ) {
if (input[0] == '*')
++n;
}
Cool, huh? :)