programming
C language
control structures
while loop
infinite loop

What is the proper equivalent of whiletrue in plain C?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In plain C, the common equivalent of while(true) is while (1) or for (;;) because any non-zero expression is treated as true. Both are valid and widely used for event loops, daemons, and embedded firmware tasks. The best choice depends on readability, standards, and how you signal loop termination.

C does not require a built-in true keyword unless you include boolean support from standard headers. Because loop conditions accept integer expressions, any non-zero constant can represent true.

Typical forms are:

  • while (1)
  • for (;;)
  • while (running) where running is controlled externally

Example:

c
1#include <stdio.h>
2
3int main(void) {
4    int i = 0;
5
6    while (1) {
7        printf("tick %d\n", i++);
8        if (i == 3) {
9            break;
10        }
11    }
12
13    return 0;
14}

This pattern is straightforward and easy to search in code reviews.

while (1) Versus for (;;)

Both compile to effectively the same control flow in modern compilers. The difference is mostly style.

while (1) emphasizes that the loop condition is always true. for (;;) emphasizes that no initialization, condition, or increment is needed.

c
1#include <stdio.h>
2
3int main(void) {
4    int count = 0;
5
6    for (;;) {
7        puts("running");
8        if (++count >= 2) {
9            break;
10        }
11    }
12
13    return 0;
14}

Pick one convention and keep it consistent across the codebase. Consistency improves maintainability more than micro-style preferences.

Using Boolean Types in Modern C

If you want a literal-style condition, include stdbool.h and use true explicitly.

c
1#include <stdio.h>
2#include <stdbool.h>
3
4int main(void) {
5    int retries = 0;
6
7    while (true) {
8        printf("retry %d\n", retries);
9        retries++;
10
11        if (retries == 5) {
12            break;
13        }
14    }
15
16    return 0;
17}

This is valid in C99 and later. It may read better for teams that also work in C++ or other languages with explicit booleans.

Controlling Exit Conditions Cleanly

Most infinite loops are not truly endless. They wait for events until a shutdown signal, an error, or a completion condition occurs. Structure exits clearly to avoid hidden termination paths.

A robust pattern is to use a state flag and break on specific events.

c
1#include <signal.h>
2#include <stdio.h>
3#include <stdbool.h>
4
5static volatile sig_atomic_t keep_running = 1;
6
7void handle_sigint(int sig) {
8    (void)sig;
9    keep_running = 0;
10}
11
12int main(void) {
13    signal(SIGINT, handle_sigint);
14
15    while (keep_running) {
16        puts("service loop");
17        // simulate work
18    }
19
20    puts("clean shutdown");
21    return 0;
22}

This avoids abrupt termination and enables cleanup code after the loop.

Embedded and Systems Programming Considerations

In firmware and low-level services, infinite loops are normal because the process owns the device lifetime. Even then, include watchdog feeding, error handling, and sleep strategies to avoid busy spinning.

A naive loop can consume full CPU unnecessarily:

c
for (;;) {
    // bad: no waiting, no event handling
}

Prefer event wait or timed pause if possible:

c
1#include <time.h>
2
3for (;;) {
4    // poll work queue
5    struct timespec ts = {0, 50 * 1000 * 1000};
6    nanosleep(&ts, NULL);
7}

That small pause can drastically reduce CPU waste in polling loops.

Readability and Static Analysis

Some static analyzers flag constant conditions unless configured. If your toolchain complains about while (1), use approved annotations or documented macros rather than obscure tricks.

For example, a project macro can communicate intent:

c
1#define FOREVER for (;;)
2
3FOREVER {
4    // event processing
5}

Use such macros sparingly. Over-abstraction for simple loops can reduce clarity.

Common Pitfalls

  • Writing infinite loops without a clear shutdown path.
  • Busy spinning without wait logic, causing high CPU usage.
  • Mixing loop styles randomly, reducing codebase consistency.
  • Hiding termination logic in deep nested branches.
  • Assuming true exists without including proper boolean support.

Summary

  • In plain C, while (1) and for (;;) are proper infinite-loop equivalents.
  • Both forms are valid and typically compile to similar machine code.
  • Use stdbool.h if explicit true improves readability.
  • Design loops with intentional exit and cleanup behavior.
  • Avoid busy loops by adding event waits or timed sleeps when appropriate.

Course illustration
Course illustration

All Rights Reserved.