Compile errors
In the first lesson, the compiler was a strict proofreader: it reads the whole recipe before anyone in the kitchen starts cooking. Let's see what it does when it finds a mistake, and how to read its notes.
Here is a program of two lines. The first is written correctly, and the second has a typo—prnt instead of print:
print("Hello!")
prnt("Hi") // ✗error: cannot find 'prnt' in scopeThe program printed nothing—not even Hello!, although the first line is correct. Let's take apart why:
- The compiler checks the whole file before the first line runs.
- On the second line, it finds the name
prnt, which Swift does not have. - It creates no finished program and reports the error.
- There is nothing to run, so not a single line runs—the correct one included.
Such an error is called a compile error: the compiler finds it before the program runs, not the running program. The proofreader sent back the whole recipe, and the kitchen followed none of its steps, not even the correct ones.
When an error is found
Interviewers like to ask: the second line has a typo—does the first one get to run? In Swift, the answer is no. A program with a compile error does not run at all, so the first line prints nothing.
In some other languages, a program starts working without a check of the whole text. There, an error like this one is found only when execution reaches its line. So the first line of our program would have printed its text. Swift works differently: first the compiler checks the whole file, and only then does the program run.
A language whose text the compiler translates in full before the program runs is called a compiled language. Swift is a compiled language.
How to read the message
The compiler writes where the error is and what is wrong. In full, the first line of the message looks like this: main.swift:2:1: error: cannot find 'prnt' in scope. Let's take it apart, left to right:
main.swiftis the file name.2is the line number.1is the character number within that line:prntstarts at the first character.erroris the kind of message: an error.cannot find 'prnt' in scopeis what is wrong: at this place in the program, there is nothing namedprnt.
Under the first line of the message, Swift repeats the part of the program around the error and marks the spot where it noticed it. In Xcode, the same message appears next to the line.
All errors at once
A proofreader marks all the mistakes in a recipe in one pass. The compiler also checks the whole file and lists every error it found:
print("Start")
prnt("Hi") // ✗
pritn("End") // ✗error: cannot find 'prnt' in scope
error: cannot find 'pritn' in scopeEach message names its own line: the second and the third. Fix the errors in order, from top to bottom, and compile again. Sometimes the later errors in the list disappear together with the first one. It also happens the other way round: some checks run only once the first errors are fixed, and then new errors appear in the list.
Warnings
Besides errors, the compiler issues warnings. With a warning, the program compiles and runs, but the compiler marks a suspicious spot. It is like a "check this" note in the margin: the proofreader still sends the recipe to the kitchen.
print("Start") // Start
"Hello!" // ✗
print("End") // Endwarning: string literal is unusedOn the second line, someone forgot to write print. The text "Hello!" stands alone, and nothing is done with it. Let's see what came out:
- The compiler found a suspicious line and issued a warning: "the text in quotes is not used."
- There are no errors, so the program was built and ran.
- It printed
StartandEnd, but notHello!.
Here the proofreader picture is off again. A proofreader would guess that the word print is missing from the line. The compiler does not know the author's intent: it reports only what it sees—the text in quotes is not used for anything.
The message starts with the word warning, not error. In a terminal, this line also ends with the tag [#NoUsage]: the name of the help page about this kind of warning. Under the message, the compiler prints a link to that page. A warning does not stop the program from running, but it is worth reading: it often points to a real slip, as it does here.
Common mistake
Two commands are written on one line:
print("one") print("two") // ✗error: consecutive statements on a line must be separated by ';'The program does not compile. The message says: commands that follow each other on one line must be separated by a semicolon. Swift accepts two commands separated by a semicolon, but Swift code does not do that: move the second print to a new line.
Key points
- The compiler checks the whole file before the program runs: on a compile error, the program does not run, and not a single line executes.
- The message names the file, the line and the character, then the kind—
errororwarning—and what is wrong. - The compiler lists every error it found; fix them from top to bottom and compile again: new ones may appear after a fix.
- With a warning, the program runs, but the warning often points to a real slip.