Let us talk about the differences between while(1) and while(0) in C language. The while(1) acts as an infinite loop that runs continually until a break statement is explicitly issued. The while(0) loop means that the condition available to us will always be false.
In most computer programming languages, a while loop is a control flow statement that allows code to be executed repeatedly based on a given boolean condition. The boolean condition is either true or false. while(1) It is an infinite loop which will run till a break statement is issued explicitly.
A while loop in C programming repeatedly executes a target statement as long as a given condition is true.
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()
).
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 !!
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With