When writing an infinite loop in a microcontroller program, do you prefer
for(;;)
or
while(1)
?
An engineer noticed that some international counterparts use
for(;;)` for infinite loops in their demo code, rather than the more common
while(1)
. Is this just a matter of personal habit, or is there a deeper reason?
The "No Difference" Viewpoint
Many developers believe there is no practical difference between the two. The perception is that
while
requires evaluating the expression in the parentheses to check if it's non-zero before jumping. However, with modern compilers,
while(1)
is optimized into an unconditional jump (a
jmp
instruction), making it identical to
for(;;)`.
Some suggest that for English speakers,
for(;;)` is easily associated with the word "forever."
Another analysis suggests it's a matter of habit. Syntactically,
for(;;)` is explicitly an unconditional loop equivalent to a `goto`. In contrast, an unoptimized
while(1)
requires a comparison operation (
cmp
) to set a register flag before a conditional jump. A
for(;;)` loop compiles directly to an unconditional jump (
jmp
). However, this offers no real performance gain, as most modern compilers like GCC and LLVM optimize
while(1)
to produce the same result.
User "Shuax" tested this using MinGW. Here is the
for
version:
#include <stdio.h>
int main()
{
for(;;)
{
printf("for\n");
}
}
Generated assembly:
And here is the
while
version:
#include <stdio.h>
int main()
{
while(1)
{
printf("while\n");
}
}
Generated assembly:
Aside from the filename, the generated assembly is identical.
Of course, the final result can vary depending on the specific code, compiler, and optimization level.
Proponent's View: Not All Compilers Are Equal
However, some argue that while modern compilers are highly optimized, this isn't always the case in embedded development, especially for MCUs. Many embedded devices use proprietary or older compilers.
One engineer pointed out that with older, less-optimized embedded compilers,
while(1)
could generate more instructions than
for(;;)` because the `while` loop is a conditional check. It might compile to something like:
label:
...
mov a, #1
jnz label
In contrast,
for(;;)` would typically compile directly to
jmp label
. Many developers have had experiences where proprietary compilers generated illegal instructions for even simple operations, casting doubt on their optimization capabilities.
Opponent's View: An Outdated Practice
Other engineers advise against this coding style, arguing that using
for(;;)` for an infinite loop is an outdated practice. From Bjarne Stroustrup to various coding standards, the consensus is that
for(;;)` is poor style.
- GJB 8114-2013 (A Chinese military standard) R-1-9-4: Infinite loops must use the
while(1)
statement; other forms such asfor(;;)` are prohibited.
CppCoreGuidelines ES.73: Prefer a while-statement to a for-statement when there is no obvious loop variable.
360 Safe Coding Rules: A
for
statement should be replaced with a while
statement when there is no explicit loop variable.
In strict coding standards, the
for
statement is intended for iterations with a clear loop variable and a defined number of cycles. The three expressions within the parentheses should handle the initialization, condition, and increment of the loop variable. This provides a clear structure that is easy to read and maintain. If there is no explicit loop variable, a
while
loop is preferred to avoid misleading developers.
The argument that
for(;;)` is more efficient is largely a relic of the past. Even without compiler optimization, this micro-optimization is negligible and not worth sacrificing code clarity for. For examples of such strict coding rules, see github.com/Qihoo360/safe-rules.
Engineer's Test: It Depends on the Compiler
Blogger "WKJay" conducted a test on an STM32F103 using the ARM CC5 compiler with optimizations turned off, measuring the results with a logic analyzer.
Result for
while(1)
:
Result for
for(;;)`:
The results show that even with an identical loop body, the
for(;;)` statement executed faster (45.863 ms) than
while(1)
(48.643 ms), a difference of about 5.7%. According to his analysis, the
for
loop generated more streamlined instructions.
Finally, he enabled the compiler's O3 optimization, and the performance difference between the two virtually disappeared (both around 12.505 ms):
From a readability perspective,
while(1)
is simple and clear, whereas
for(;;)` is more ambiguous. For modern compilers, the two are functionally identical. Furthermore, with high-frequency chips, the overhead of one or two extra machine instructions is insignificant. In such cases, the best practice is to choose the form that is most readable.