What purpose does while(1);
serve ? I am aware while(1)
(no semicolon) loops infinitely and is similar to a spinlock situation. However I do not
In AVR chipsets programming (using C programming language) this statement is frequently used, It plays a role like event loop.
Suppose I want to design a count-up counter, So I can use this code for implementing it:
void interrupt0() {
/* check if key pressed, count up the counter */
}
void main() {
/* Common inits */
/* Enable interrupt capability and register its routine */
/* Event loop */
while(1);
}
Please note that all valid statements of the language do not have to serve a purpose. They are valid per the grammar of the language.
One can build many similar "useless" statements, such as if (1);
.
I see such statements as the conjunction of a conditional (if
, while
, etc.) and the empty statement ;
(which is also a valid statement although it obviously serves no specific purpose).
That being said, I encountered while (1);
in security code. When the user does something very bad with an embedded device, it can be good to block them from trying anything else.
With while (1);
, we can unconditionally block a device until an accredited operator manually reboots it.
while(1);
can also be part of the implementation of a kernel panic, although a for(;;) {}
loop seems to be a more common way of expressing the infinite loop, and there might be a non-empty body (for instance to panic_blink()).
Since the condition is always true, we can say that we are using a logic tautology as known in mathematics. While the loop proofs to be always true it won´t stop looping unless forced by the code or until resources have collapsed.
This is tagged C, but I'll start with a C++ perspective. In C++11, the compiler is free to optimize while(1);
away.
From the C++11 draft standard n3092, section 6.5 paragraph 5 (emphasis mine):
A loop that, outside of the for-init-statement in the case of a for statement,
— makes no calls to library I/O functions, and
— does not access or modify volatile objects, and
— performs no synchronization operations (1.10) or atomic operations (Clause 29)
may be assumed by the implementation to terminate. [Note: This is intended to allow compiler transformations, such as removal of empty loops, even when termination cannot be proven. — end note ]
The C11 standard has a similar entry, but with one key difference. From the C11 draft standard n1570, (emphasis mine):
An iteration statement whose controlling expression is not a constant expression,156) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.157)
156) An omitted controlling expression is replaced by a nonzero constant, which is a constant expression.
157) This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.
This means while(1);
can be assumed to terminate in C++11 but not in C11. Even with that, note 157 (not binding) is interpreted by some vendors as allowing them to remove that empty loop. The difference between while(1);
in C++11 and C11 is that of defined versus undefined behavior. Because the loop is empty it can be deleted in C++11. In C11, while(1);
is provably non-terminating, and that is undefined behavior. Since the programmer has invoked UB, the compiler is free to do anything, including deleting that offending loop.
There have been a number of stackoverflow discussions on optimizing compilers deleting while(1);
. For example, Are compilers allowed to eliminate infinite loops?, Will an empty for loop used as a sleep be optimized away?, Optimizing away a "while(1);" in C++0x. Note that the first two were C-specific.
As others have said, it's just an infinite loop that does nothing, completely analogous to
while (1) {
/* Do nothing */
}
The loop with the semicolon does have a body. When used as a statement, a single semicolon is a null statement, and the loop body consists of that null statement.
For readability, to make it plain to the reader that the null statement is the body of the loop, I recommend writing it on a separate line:
while (1)
;
Otherwise it is easy to miss it at the end of the "while" line, where there usually isn't a semicolon, and the reader can mistake the next line as the body of the loop.
Or use an empty compound statement instead.
I think that the reason that while(1);
is used is because earlier in the code an EventHandler or interrupt has been set on this thread. Using standard Thread Safe locking code can be fairly costly (in time) when you know that your code will only 'wait' for a very short amount of time.
Therefore you can set up the interrupt and 'spin' using while(1);
which, although is a Busy Wait (doesn't let the CPU Idle/service other threads) takes up very few cycles to set up.
In summary, it's a 'cheap' spinlock while your thread waits for an interrupt or Event.