56

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

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
Abhijit K Rao
  • 1,097
  • 1
  • 8
  • 18
  • 3
    It is simply another method for providing an infinite loop that will be interrupted from within its code block. Similar to `for (;;)`. There are numerous examples within the man pages where you can find infinite loops with a later `break` to exit the loop after the desired number of iterations – David C. Rankin Jun 18 '14 at 06:51
  • 12
    @DavidC.Rankin a `while(1);` (notice the ; at the end) loop has no body where a break could happen – mch Jun 18 '14 at 06:53
  • Ahh.. you are correct sir. In that case, your `do {...} while (1);` seems the only obvious use. – David C. Rankin Jun 18 '14 at 06:57
  • 4
    I would recommend to point out in the question one more time, that you mean exactly `while(1);`, not `while(1)`. It's easy to miss, and it causes confusion. – FreeNickname Jun 18 '14 at 06:58
  • 26
    IMHO `while (1);` is the best way to drain the battery of a laptop... – Axel Jun 18 '14 at 09:01
  • 1
    What about the scenario where you're waiting for a Signal and have a sigaction set and you want to pause the program until then? It's not optimal but it does sound like a use case. – Benjamin Gruenbaum Jun 18 '14 at 14:26
  • Either while(1) is undefined behavior or the compiler can assume that this loop does terminate (can't remember which). The standard says that. This is not safe code, no matter what the intention is. – usr Jun 18 '14 at 15:59
  • 1
    Actually, you're wrong: `while (1)` is an incomplete statement. The semicolon terminates the (empty) loop body. – Ryan Reich Jun 18 '14 at 16:53
  • Some versions of GCC now optimise this out, the language is allowed to assume every function will either: edit a volatile, return a value, run a system call or exit (I may be missing one). – Vality Jun 19 '14 at 00:35
  • 3
    `#define ever ;;` `#define loop ;` `for (ever) loop` – Zaq Jun 19 '14 at 01:07
  • @RyanReich: Perhaps a nitpick, but the loop body is not empty. The semicolon here is a null statement, and the loop body consists of that null statement. – Thomas Padron-McCarthy Jun 19 '14 at 03:51
  • 1
    @Thomas I suppose it looked like I knew some technical terms because I was trying to be precise, but I actually don't. What's important, I guess, is that the expression inside the single statement of which the loop body consists in its entirety is empty. And this is signaled by the semicolon appearing where it does, and not by it not appearing. – Ryan Reich Jun 19 '14 at 04:35
  • 1
    In the *old days* (like really a long time ago), when you program on a PC in BASIC writing a program that will do things based on key events, how do you hang the "main" thread so that the program doesn't end? You do a ``100 GOTO 100`` which in effect is the same as this ``while(1);`` in C. All the functionalities of the program rest within the event handlers. Essentially, ``while(1);`` is sort of a Windows "message pump loop" that doesn't pump messages. The only time when it makes sense is where the system has event triggers that can function outside of this loop. – Stephen Chung Jun 25 '14 at 01:34
  • @usr in [C++ this is UB](http://stackoverflow.com/q/3592557/1708801) but in [C11 this is not UB since it uses a constant expression for the controlling statement](http://stackoverflow.com/q/2178115/1708801). – Shafik Yaghmour Jan 05 '17 at 18:24
  • @RyanReich the grammar of the while loop requires a *statement* afterwards, in this case the *statement* is a [null statement](http://stackoverflow.com/a/22155271/1708801). – Shafik Yaghmour Jan 05 '17 at 18:40

12 Answers12

89

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

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
dureuill
  • 2,526
  • 17
  • 24
  • 5
    Another usecase for an empty infinite loop is when implementing `assert()`, which is of course very much like your security example. – unwind Jun 18 '14 at 07:12
  • That security code is not very secure. A compiler is free to optimize `while(1);` away. – David Hammen Jun 18 '14 at 11:34
  • 3
    @DavidHammen aren't compiler optimizations supposed to remain functionally equivalent? – svvac Jun 18 '14 at 11:38
  • 1
    @swordofpain they are supposed, yes. But see https://groups.google.com/forum/#!topic/comp.std.c/vFfu3wMM0ZI – dureuill Jun 18 '14 at 11:49
  • 2
    @DavidHammen I'm talking about very specific toolchains and very specific compilers. People doing this usually know what they're doing and they are not writing portable code. – dureuill Jun 18 '14 at 12:06
  • @swordofpain they are supposed to preserve *observable behavior*. "the program takes a long time to execute" is not observable behavior as defined by the C/C++ standards. Not even if "a long time" equals infinity. At least in C++11, there is wording that allows the implementation to assume that all side-effect-free loops are going to terminate (and by implication, they can be optimized away if the body is completely empty). I don't know if the C standard has equivalent wording – jalf Jun 18 '14 at 13:13
  • Executing unreachable code isn't a change in observable behaviour? Wow, I respect C less every day. – harold Jun 18 '14 at 13:43
  • 2
    @DavidHammen As I understand, a C++ compiler is free to optimize that loop away, but not a C compiler. – Kevin Jun 18 '14 at 14:36
  • 1
    cc @harold ^ C++, not C. – Kevin Jun 18 '14 at 14:36
  • By the way, `for (;;) {}` is more popular because it doesn't generate compiler warnings – Izkata Jun 18 '14 at 19:30
  • @harold: It may be a change in observable behavior, but since the program invokes undefined behavior, the standard doesn't care. – user2357112 Jun 20 '14 at 04:08
  • 1
    @user2357112 that's not actually an argument, the standard isn't god and right by definition, the standard is the problem here – harold Jun 20 '14 at 07:04
  • @harold: Are you saying that infinite, side-effect-free loops should not be undefined behavior? If so, I don't really have anything to say. There are arguments for or against it. I haven't formed an opinion. If you're saying that undefined behavior shouldn't result in such consequences, you're asking for C to fill a very different niche in the space of computer language design. – user2357112 Jun 20 '14 at 07:19
  • 4
    @user2357112 that would actually just be asking it to really fill the niche it thinks it's filling. It's not some weird feature only seen in highly specialized languages or anything like that. It's just the basic principle of actually doing the thing you wrote it should do, and yes I know C is too good for that in general, it would rather take your code as a suggestion and then do something random "because it can". – harold Jun 20 '14 at 07:34
  • @harold: When C was written, it was pretty well expected that a compiler would generate an executable that would perform the operations specified by each statement, in the order the statements were specified to execute; there was great usefulness in having a language whose operations tended to map to machine instructions in predictable fashion. Such usefulness hasn't gone away. There is still a need for a language that works the way C was originally designed and intended to work. Unfortunately, the name "C" has been taken over as representing something altogether different... – supercat Aug 05 '15 at 16:40
  • ...(and totally unsuitable for many of the purposes C was designed to fulfill). I'm not sure what needs to happen to reclaim "C" as a usable systems-programming language which takes the philosophy that programmers should supply their safety gear, rather than the hyper-modern philosophy that compilers should eliminate any safety gear that programmers try to include if they (the compilers) determine that it doesn't meet the compiler's requirements. – supercat Aug 05 '15 at 16:41
30

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 !!

a.atlam
  • 742
  • 5
  • 17
  • 4
    So in plain English, it's used to keep your program from exiting until you're ready, even when your program isn't doing anything. Yes? – jpmc26 Jun 18 '14 at 22:55
  • Yes very well said, until an event or an interrupt is triggered. – a.atlam Jun 19 '14 at 04:55
  • @jpmc26 Basically in embedded systems, unlike your PC or a normal server, there's nothing to exit to. There is often no OS where a program can exit to. Therefore the default behaviour if your code ends is the program counter will continue counting and execute random noise in RAM as CPU instructions. – slebetman Jul 24 '23 at 19:48
18

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.

Community
  • 1
  • 1
David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • Are there actually any compilers that do that? –  Jun 18 '14 at 14:15
  • 8
    Agreed that `while (1);` is non-terminating, but why would anyone call that "undefined behavior"? It seems well defined to me. It may or may not be _desirable_ behavior, but for a compiler to optimize it away is changing the meaning of the program, and thus bad. – Phil Perry Jun 18 '14 at 14:15
  • 2
    @Tibor: Intel, clang, and others do exactly this. That extra clause in the C11 standard ("whose controlling expression is not a constant expression") appears to allow `while(1);`. However, C11 standard 5.1.2.3 p 4 says "In the abstract machine, all expressions are evaluated as specified by the semantics. **An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced** ..." So there's still an out in C11 for compiler vendors to optimize `while(1);` away. – David Hammen Jun 18 '14 at 16:03
  • @DavidHammen *"An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced"* `while (1);` is a statement, not an expression. – ouah Jun 18 '14 at 18:31
  • Also, I would argue that it has a _very predictable_ side effect. Judgment of "needed" is a bit fuzzier. – Michael Jun 18 '14 at 20:51
  • Side effects include performing I/O, changing the value of a variable. Wasting CPU time does not count a side effect. – David Hammen Jun 18 '14 at 21:34
  • To be specific, C11 5.1.2.3 P 2, "*Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.*" Wasting CPU time does not qualify as a "side effect". – David Hammen Jun 18 '14 at 22:09
  • @Tibor yes there are, I [made a few comments here about this](http://stackoverflow.com/questions/41320725/is-infinite-loop-still-undefined-behavior-in-c-if-it-calls-shared-library#comment70109570_41320725) on a related question. – Shafik Yaghmour Jan 05 '17 at 18:32
9

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.

ouah
  • 142,963
  • 15
  • 272
  • 331
8

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.

Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
  • You could use `while(1) pause();` and that is just about the only thing the `pause` system call is good for. In any other context using `pause` is likely a bug, which could be fixed by using `sigsuspend` with proper parameters. – kasperd Jun 18 '14 at 21:35
5

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.

waldol1
  • 1,841
  • 2
  • 18
  • 22
4

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.

Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
1
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.

Zach P
  • 1,731
  • 11
  • 16
  • 2
    the question is about `while (1);`, not simply `while (1)`. The semicolon is significant; it indicates that there is *no* body for the loop. :) – jalf Jun 18 '14 at 08:02
  • @jalf didn't notice the semicolon, my bad, fixed – Zach P Jun 18 '14 at 08:08
  • 3
    Although the top-voted answer also addresses the security issues, the top-voted answer clarifies that it's only embedded systems where it's useful. For pretty much any program running on any multitasking system, it's completely and utterly useless for security. –  Jun 18 '14 at 14:46
1

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.

ST3
  • 8,826
  • 3
  • 68
  • 92
1

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);
} 
frogatto
  • 28,539
  • 11
  • 83
  • 129
1

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.

Th3Minstr3l
  • 322
  • 2
  • 7
0

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.