Infinite loops in C – Use and Debugging

Infinite loop is a looping construct that iterates forever. In programming life either intentionally or unintentionally, you come across an infinite loop. Generally a program in an infinite loop either produces continuous output or does nothing. Infinite loops are also known as indefinite or endless loop.

As a novice programmer, you must know how to debug an infinite loop. As an intermediate programmer you must know how and when to use infinite loop. Let us first learn when to use infinite loop and how to define.

Infinite loop - use and debugging

When to use an infinite loop?

In programming, infinite loop plays a significant role. When a programmer wants an application to do same task repeatedly forever. He must use infinite loop for the purpose.

Nearly all applications are in infinite loop, that accept user input continuously, process the input and generate some output until user manually exit from the application.

  • All operating systems are in an infinite loop. It must not exit after doing some task. Therefore, it goes in an indefinite loop. Which terminate when user manually shutdown the system.
  • All servers are in infinite loop. Server must actively listen to client requests indefinitely and give proper response. Therefore, it goes in an endless loop until, network administrator shutdown the server manually.
  • All game engines puts itself to an infinite loop. Any game engine actively accept user input, run algorithms, draw graphics and play audio based on user interaction indefinitely, until user exit from the game.

Implement an infinite loop in your program, if your program does some task repeatedly and the loop termination condition is not known prior to the developer. For example – accept user input, processes the input and generate some output until user manually terminate the program.

Examples of defining infinite loop

There are numerous ways to write an infinite loop. Here I am listing some of the general preferred infinite loop structures. You can use any of the below approach to define infinite loop.

Define infinite for loop

for(;;)
{
    // Do your task here
}

All parts of a for loop is optional. In the above loop structure there is no condition to check and terminate the loop. Hence, the loop iterates indefinitely.

Define infinite while loop

while(1)
{
    // Do your task here
}

In the above while loop inside the loop condition i.e. while(1) you can use any non-zero integer to make it infinite loop. A non-zero integer in C is treated as true whereas zero is treated as false.

Define infinite do...while loop

do 
{
    // Do your task here
} while(1); // You can use any non-zero integer

Define infinite loop using goto statement

infinite_loop:
    // Do your task here
goto infinite_loop;

In above program the goto statement transfer program control indefinitely to the infinite_loop label.

Define infinite loop using macros

#define FOREVER for(;;)

int main()
{
    FOREVER
    {
        // Do your task here
    }
    
    return 0;
}

This is little tricky but one of my favorite. It defines a constant FOREVER. All occurrences of FOREVER in the program is replaced by the constant value i.e. for(;;) during the C compilation process.

We learned various ways to define an infinite loop. However, the second approach using while(1) is the best way to implement an infinite loop.

When using infinite loop, you must use conditional break statement inside the loop, to terminate on user choice. For example –

while(1)
{
    // Do your task here
    if(condition)
    {
        // User chooses to exit 
        break;
    }
}

How to debug unintentional infinite loops?

Almost all novice programmers once in their life faces an infinite loop unknowingly. Unintentional infinite loops are general-purpose loop that goes indefinite due to some logical bug. Not only novice programmers but experienced programmers also faces the pain of unintentional infinite loop. They are hard to trace and for beginners it is a nightmare to debug infinite loops.

Below are some debugging measures must be taken by novice programmers in the process of tracing unintentional infinite loop.

  • Watch semicolons properly. I have seen many situations when a single semicolon eats entire loop body, resulting in an indefinite loop.
    int num = 1;
    
    while(num <= 10); // <-- Semicolon should be removed
    {
        // Do some task here
        num++;
    }
  • Check logical conditions properly. Either intentionally or a typing mistake, programmers generally misinterpreted the use of assignment operator = and relational operator ==.
    char choice = ‘n’;
    
    while(choice = ‘y’) // <-- = must be replaced by == operator
    {
        // Do some task here
    }
  • Use of wrong update statements or loop conditions can ruin your entire loop. This is common to novice programmers.
    int i;
    
    for(i=100; i>=1; i++) // <-- i++ must be replaced by i--
    {
        // Do your task here
    }
  • Never underestimate floating-point errors. Be careful while using float values inside loop. It may turn to an indefinite loop.
    float num = 0.1f;
    
    while(num != 10.0f) // <-- Runs indefinitely due to floating point error
    {
        // Do your task here
    
        // Adds 0.1 to num with some floating point error
        num = num + 0.1f;
    }

    If you don’t believe me once compile and execute the above code.

    To debug above code always use rounding functions. Either make use of round(), floor() or ceil() as per your requirement. For this case I am using floor() function.

    float num = 0.1f;
    
    while(floor(num) != 10.0f) // <-- Floating point error is rounded 
    {
        // Do your task here
    
        // Adds 0.1 to num with some floating point error
        num = num + 0.1f;
    }
  • Be careful while breaking from nested loop. break statement terminate nearest loop. Breaking from a nested inner loop will not terminate the entire loop.
    int i, j;
        
    while(1) // Infinite loop
    {
        for(i=1; i<=10; i++) // Some sample loop
        {
            if(i%2 == 0)
            {
                break; // <-- break will only terminate the inner loop
            }
        }
    }

Still puzzled with infinite loops write down your queries in down below in comments section. Or practice exercises on loops to learn where and how to use infinite loops.

Happy coding 😉