Start learning free

LESSON 123 OF 415 · WHILE LOOPS & FOR LOOPS

Infinite While Loops in Swift: Causes and Fixes

Lesson Read the full explanation

Loops bring great power but also great responsibility. The biggest danger when using loops is writing an infinite loop.

An infinite loop is a loop that never terminates. For example, if we forget to increment i in our previous example:

var i = 1
while i < 5 {
    print(i)
    // i += 1 // forgot this
}

This program will never terminate as i will always have value 1 and thus the condition i < 5 will always be satisfied.

The program would basically print 1 forever never exiting the while loop.


Pro Tip:

As programmers, we want to make sure we never write infinite loops as they make our program run forever and completely unusable.


Assignment
Follow the Coding Tutorial and practice with infinite while loops!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 1
    Ctrl + Enter to check

    SWIFT · WHILE LOOPS & FOR LOOPS

    Infinite While Loops in Swift, explained

    What an infinite loop is

    A while loop repeats its body as long as its condition is true. If nothing inside the body ever makes the condition false, the loop never ends and the program keeps running until it is stopped from outside. That is an infinite loop.

    The classic cause is forgetting to update the variable the condition depends on:

    var i = 1
    while i < 5 {
        print(i)
        // i += 1 // forgot this
    }
    

    Here i stays 1, so i < 5 is true on every pass and the program prints 1 forever. Adding i += 1 inside the body fixes it: the loop prints 1, 2, 3, 4 and stops when i reaches 5.

    A subtler cause: waiting for a value that is skipped

    The lesson's exercise shows a second way to get stuck. The loop updates its counter correctly, but the condition waits for one exact value that the counter jumps over:

    var counter = 15
    while counter != 0 {
        print(counter)
        counter -= 2
    }
    

    The goal is to print the odd numbers from 15 down to 1. Follow the counter through the last passes: 3, then 1, then -1. Subtracting 2 from an odd number always gives an odd number, so counter is never 0. The condition counter != 0 is true on every pass, and the loop goes on with -1, -3, -5 and so on.

    Swift's Int is 64 bits and arithmetic that overflows crashes the program, so this loop would not run forever in the strict sense. It would count down for an astronomically long time and then trap, which is no better in practice.

    Fixing the exercise

    1. Find what the loop is waiting for. The condition waits for counter to equal 0, and that never happens.
    2. Ask what you really mean. You want to keep going while there are positive numbers left, not until you hit one particular number.
    3. Use a range check. Replace != with >. Once the counter passes below 1, the condition is false and the loop ends, whether or not the counter lands on a specific value.
    var counter = 15
    while counter > 0 {
        print(counter)
        counter -= 2
    }
    

    This prints 15, 13, 11, 9, 7, 5, 3 and 1. After printing 1 the counter becomes -1, the condition -1 > 0 is false, and the loop stops.

    Why != is risky and > is safer

    A condition with != only stops the loop if the counter lands exactly on the target. That works when the step is 1, but it breaks as soon as the step is larger or the start value changes. The same loop started at 14 reaches 0 and stops:

    var d = 14
    while d != 0 {
        print(d, terminator: " ")
        d -= 2
    }
    
    14 12 10 8 6 4 2 
    

    So the code looks right for one starting value and hangs for another. A comparison such as >, <, >= or <= describes a whole range of values, and the loop ends once the counter leaves that range, however it got there.

    How to avoid infinite loops

    • Check the update. Every variable in the condition should change inside the body, and it should change in the direction that makes the condition false.
    • Prefer range comparisons. Use <, >, <= or >= when a counter moves toward a limit.
    • Trace the last passes by hand. Write down the counter for the final few iterations and check that the condition really turns false.
    • Use a for loop when you know the range. A for over a range or a stride ends by itself and has no counter for you to forget.

    Key takeaways

    • A while loop ends only when its condition becomes false.
    • Forgetting to update the counter, or updating it in the wrong direction, makes the loop infinite.
    • A counter that skips over the exact value in an != condition never stops the loop.
    • A range check such as counter > 0 stops the loop even when the counter jumps past the boundary.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free