For vs While: Which Loop to Use in MCU Programming?

On Zhihu, there is a classic question that has sparked intense discussion.

An engineer found that foreign engineers use for(;;) for infinite loops in demos, instead of the commonly used while(1). Is this merely a matter of personal habit, or is there a deeper significance?

No Difference Party: It’s All Psychological

Most netizens believe there is no real difference between the two. Often, it is just psychological; foreign engineers think that while needs to evaluate whether the expression in parentheses is non-zero before jumping. However, after careful optimization by the compiler, while(1) will also be optimized into an unconditional jump (jmp instruction), so there’s no difference from for(;;).
Some have stated that for(;;) easily associates with “forever” for native English speakers.
Netizens analyzed that it is likely a matter of habit. In fact, the two syntaxes while(1) and for(;;) do have a syntactical difference: for(;;) clearly indicates a loop, equivalent to a goto that jumps indefinitely without a comparison condition.
Without compiler optimization, while requires a cmp operation to set the ZF register before it can perform conditional jumps with jne and je. Meanwhile, for(;;) is an explicit unconditional jump to eip, without conditional jumps.
However, it actually doesn’t matter; this cannot improve any performance of code execution. Because modern compilers mostly optimize the results to be nearly identical to that of for(;;).
Everything you consider for optimization, the compiler can accomplish for you, because compilers (especially open-source ones like GCC and LLVM) are developed and improved by programmers from all over the world, and their optimization capabilities far exceed manual code improvements.
A netizen named “Shuax” used mingw to compile and conducted a practical test:
For version
#include<stdio.h>int main(){  for(;;)  {    printf("for\n");  }
Generated assembly:
For vs While: Which Loop to Use in MCU Programming?
While version
#include<stdio.h>int main(){  while(1)  {    printf("while\n");  }
Generated assembly:
For vs While: Which Loop to Use in MCU Programming?
You will find that aside from the file names being different, everything else is the same.
Of course, it should be noted that different codes, different compilers, and different optimization levels may yield different final results.

Proponents’ View: Where Are Good Compilers?

However, some have rebutted that while modern compilers optimize well and there is no difference in execution, in actual embedded work, especially in MCU programming, the compilers are not always that good.
An engineer stated that many embedded devices only have dedicated compilers, and in the past, especially when embedded compilers were poorly optimized, while(1) would have several more statements than for(;;).
Because while contains a condition, it would translate to:
label:    ……    mov a, #1    jnz label 
In this case, for(;;) would generally only be jmp label.
Many people have had similar experiences and expressed that some proprietary compilers can generate illegal instructions for expressions like (int)a<<0, leading to doubts about whether the accompanying chips can handle optimized instructions.

Opponents’ View: This Coding Style is Outdated

Some engineers have called for not adopting this coding style; it is already 2024, and using for(;;) to indicate an infinite loop is now considered an outdated style.
From Dr. Stroustrup to our national military standards, it is believed that for(;;) is a poor style. See:
  • GJB 8114-2013 R-1-9-4: Infinite loops must use the while(1) statement; using for(;;) and other forms is prohibited.

  • CppCoreGuidelines ES.73: Prefer a while-statement to a for-statement when there is no obvious loop variable.

  • 360 safe rules: When there is no explicit loop variable in a for statement, it should be replaced with a while statement.

Why is this so? Within a stricter regulatory framework, for statements are specifically used to implement iterative algorithms with a clear number of iterations and loop variables. The three expressions in parentheses should focus on initializing the loop variable, judging the loop condition, and incrementing the loop variable. This creates a clear static structure for the loop, making it easier to read and maintain. If there is no explicit loop variable, a while loop should be used to avoid misleading the code maintainers.
Some say for(;;) indicates an unconditional loop, while while(1) requires a conditional check, which is slower than for(;;). There is some truth to this, but that was long ago. Even without compiler optimization, this overhead will not become a performance bottleneck, and maintaining a clear static structure of the code is more important!
Similar strict code auditing rules, such as those from the national military standards, can be referenced at: github.com/Qihoo360/safe-rules
For vs While: Which Loop to Use in MCU Programming?

Engineers Test: Related to Compiler and Optimization

Public account blogger “WKJay” also conducted tests on STM32F103 and ARMCC5, running the two logics separately (without compiler optimization) to check the output results from the logic analyzer.
Results of while(1) logic:
For vs While: Which Loop to Use in MCU Programming?
Results of for(;;) logic:
For vs While: Which Loop to Use in MCU Programming?
The results show that although the loop bodies are identical, the execution results indicate that for(;;) executes faster (45.863ms) than while(1) (48.643ms), by about 5.7%.
According to his analysis, the instructions for for are more concise, while those for while are relatively more complex; in simple terms, for takes a shortcut, while while goes around.
For vs While: Which Loop to Use in MCU Programming?
Finally, he enabled the compiler’s O3 optimization, and the results showed that there was virtually no difference between the two (12.505ms):
For vs While: Which Loop to Use in MCU Programming?
From a readability perspective, while(1) is simple and clear, while for(;;) is much more ambiguous. However, for some older dedicated compilers, careful consideration may be needed regarding which form to use.
For modern compilers, the two are effectively the same. Moreover, high-frequency chips do not care about one or two machine instructions, so in this case, write whichever is more visually appealing.

References

[1] Zhihu: https://www.zhihu.com/question/23043337

[2] WKJay: Extreme Optimization, Who is Faster Between while(1) and for(;;)? 2024.1.28. https://mp.weixin.qq.com/s/T21DLqOkqe38XuG3Z3I8SQ

[3] Embedded Column: What is the Difference Between while(1) and for(;;) in Microcontroller Code? 2023.12.1. https://mp.weixin.qq.com/s/mq6sjy1CMPXHIfPpDOt-_A

[4] Embedded Linux: Do You Use while(1) or for(;;) to Write Loop Code? 2021.1.20. https://mp.weixin.qq.com/s/4Y2x2Xm_0rc9_DwdLgYWMA

Leave a Comment

×