Purpose of while(1); statement in C

CWhile Loop

C Problem Overview


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 see where while(1); could be used ?

Sample code

if(!condition)
{ 
  while(1);
}

Note: This is not a case of do-while() or plain while(1).

C Solutions


Solution 1 - C

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()).

Solution 2 - C

If you dig down to assembly, (this is easier to grasp from an embedded systems point of view, or if you tried to program a bootloader)

you will realize that a while loop is just a jmp instruction ... ie

(pseudo code: starting loop address)
add ax, bx
add ax, cx
cmp ax, dx
jz  (pseudo code: another address location)
jmp (pseudo code: starting loop address)

Lets explain how this works, the processor will keep executing instructions sequentially ... no matter what. So the moment it enters this loop it will add register bx to ax and store in ax, add register cx to ax and store to ax, cmp ax, dx (this means subtract dx from ax) the jz instruction means jump to (another address location) if the zero flag is set (which is a bit in the flag register that will be set if the result of the above subtraction is zero), then jmp to starting loop address (pretty straight forward) and redo the whole thing.

The reason I bothered you with all this assembly is to show you that this would translate in C to

int A,B,C,D;
// initialize to what ever;

while(true)
{
A = A + B;
A = A + C;

if((A-D)==0)
{break;}

}

// if((X-Y)==0){break;} is the 
// cmp ax, dx
// jz  (pseudo code: another address location)

So imagine the senario in assembly if you just had a very long list of instructions that didn't end with a jmp (the while loop) to repeat some section or load a new program or do something ... Eventually the processor will reach the last instruction and then load the following instruction to find nothing (it will then freeze or triple fault or something).

That is exactly why, when you want the program to do nothing until an event is triggered, you have to use a while(1) loop, so that the processor keeps jumping in its place and not reach that empty instruction address. When the event is triggered, it jumps to the event handler instructions address, executes it, clears the interrupt and goes back to your while(1) loop just jumping in its place awaiting further interrupts. Btw the while(1) is called a superloop if you want to read more about it ... Just for whoever that is insanely itching to argue and comment negatively at this point, this is not an assembly tutorial or a lecture or anything. It's just plain English explanation that is as simple as possible, overlooking a lot of underlying details like pointers and stacks and whatnot and at some instance over simplifying things to get a point across. No one is looking for documentation accuracy over here and I know this C code won't compile like this, but this is only for Demo !!

Solution 3 - C

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.

  1. 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, https://stackoverflow.com/questions/2178115/are-compilers-allowed-to-eliminate-infinite-loops, https://stackoverflow.com/questions/10300253/will-an-empty-for-loop-used-as-a-sleep-be-optimized-away, https://stackoverflow.com/questions/3592557/optimizing-away-a-while1-in-c0x. Note that the first two were C-specific.

Solution 4 - C

An usage on embedded software is to implement a software reset using the watchdog:

while (1);

or equivalent but safer as it makes the intent more clear:

do { /* nothing, let's the dog bite */ } while (1);

If the watchdog is enabled and is not acknowledged after x milliseconds we know it will reset the processor so use this to implement a software reset.

Solution 5 - C

I assume that the while(1); is not associated with a do loop...

The only semi-useful implementation of while(1); I have seen is a do-nothing loop waiting for an interrupt; such as a parent process waiting for a SIGCHLD, indicating a child process has terminated. The parent's SIGCHLD handler, after all child processes have terminated, can terminate the parent thread.

It does the trick, but wastes a lot of CPU-time. Such a usage should perhaps perform some sort of sleep to relinquish the processor periodically.

Solution 6 - C

One place that I have seen a while(1); is in embedded programming.

The architecture used a main thread to monitor events and worker threads to handle them. There was a hardware watchdog timer (explanation here) that would perform a soft reset of the module after a period of time. Within the main thread polling loop, it would reset this timer. If the main thread detected an unrecoverable error, a while(1); would be used to tie up the main thread, thus triggering the watchdog reset. I believe that assert failure was implemented with a while(1); as well.

Solution 7 - C

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.

Solution 8 - C

while(1);

is actually very useful. Especially when it's a program that has some sort of passcode or so and you want to disable the use of the program for the user because, for an example, he entered the wrong passcode for 3 times. Using a while(1); would stop the program's progress and nothing would happen until the program is rebooted, mostly for security reasons.

Solution 9 - C

This may be used to wait for Interrupt. Basically you initialize all things you need and start waiting for some thing to occur. After that some specific function is called and executed, after that it goes back to waiting state.

That thing could be button pressed, mouse click/move, data received and etc.

What is more I would say, similar stuff is really often used by UI frameworks. While it waits for signals about user actions.

Solution 10 - C

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);
} 

Solution 11 - C

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.

Solution 12 - C

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbhijit K RaoView Question on Stackoverflow
Solution 1 - CdureuillView Answer on Stackoverflow
Solution 2 - Ca.atlamView Answer on Stackoverflow
Solution 3 - CDavid HammenView Answer on Stackoverflow
Solution 4 - CouahView Answer on Stackoverflow
Solution 5 - CMahonri MoriancumerView Answer on Stackoverflow
Solution 6 - Cwaldol1View Answer on Stackoverflow
Solution 7 - CThomas Padron-McCarthyView Answer on Stackoverflow
Solution 8 - CZach PView Answer on Stackoverflow
Solution 9 - CST3View Answer on Stackoverflow
Solution 10 - CfrogattoView Answer on Stackoverflow
Solution 11 - CTh3Minstr3lView Answer on Stackoverflow
Solution 12 - Cdeveloperto_jrmView Answer on Stackoverflow