Errors the compiler gives you
How a compiler message is laid out, the four you will meet first, and why you fix only the top one.
Every C++ programmer, at every level of experience, spends part of the day reading compiler errors. That is not a sign that something has gone wrong. It is the arrangement you signed up for: you write, the compiler checks, and it tells you where it lost the thread.
C++ error messages have a reputation for being unreadable. For some kinds of code that reputation is thoroughly earned, and you will meet those eventually. The ones you will hit this week are not like that. They have a fixed shape, and once you can see the shape you can read most of them at a glance.
The shape of a message
main.cpp:5:28: error: expected ';' before 'return'
5 | std::cout << "Hello.\n"
| ^
| ;
6 | return 0;- `main.cpp` is the file. In this course there is only ever one.
- `5:28` is the position: line 5, twenty eight characters along.
- `error:` is the severity. An
error:means no program was produced. Awarning:means the compiler built your program anyway but suspects you will regret something. - `expected ';' before 'return'` is the complaint itself, and it is usually literal. It expected a semicolon and found the word
return. - The lines underneath echo your own code with a
^under the exact spot, and sometimes, as here, print what it wanted to see there.
Four you will meet in your first week
Each of the next four snippets is broken on purpose. Run it, read the message, then make the change the note describes and run it again. Making these mistakes deliberately now is much cheaper than meeting them for the first time in your own code at eleven at night.
First, the missing semicolon. Every instruction inside a function ends with one. Leave it off and the compiler simply keeps reading, joins your line to the next, and complains at the first word that cannot possibly follow.
Depending on your compiler, the message points either at the end of the std::cout line or at the return below it, which was the first word that could not follow. Either way the semicolon belongs on the end of the std::cout line. Put it there and run it again.
Second, a name the compiler has never heard of. cout on its own is not a name C++ knows, because the one you want lives in the namespace std. The message for this is unusually helpful, because modern compilers guess what you meant and say so.
Read the 'did you mean' part of the message, then do exactly what it suggests: put std:: in front of cout and run it again.
Leave the std:: off three times and you get the complaint three times, once for each line that used the name. Three messages here really are three separate problems that happen to share a cause.
Fix only the first cout and run it again: three messages become two. Then fix the other two.
Third, a missing header. The name can be spelled perfectly and still not be found, if the header that describes it was never pasted in.
Add #include <iostream> as the first line and run it again. Notice that the complaint was about line 2 while the fix belongs at the top of the file.
Fourth, a bracket that is opened and never closed. This one is different in kind, because the compiler cannot tell where the mistake was. It reads all the way to the end of the file still waiting to be closed, so it reports the problem at the very end, however far that is from the cause.
The message points at the very last thing you wrote, because that is where the compiler ran out of file while still waiting, and it often adds a second line pointing back at the { it was trying to match. Add a } on a line of its own at the bottom and run it again.
Fix the first one, then compile again
One mistake often produces a page of errors. Once the compiler has lost its place, everything it reads afterwards is measured against a wrong idea of where it is, and it will complain about lines that are entirely correct.
So the routine is: read the first error, fix that one thing, compile again. Do not work down the list. It is completely ordinary for thirty messages to disappear because one semicolon came back.
One closing brace typed three lines too early, and the compiler complains about every line below it, none of which is wrong. It thinks main ended at that brace, so the lines after it are no longer inside any function and no longer make sense where they are. Delete the } on its own after the Cutlery. line and run it again: the whole list goes at once.
And here is an error that is not the compiler's at all. Remember from the first lesson that after the compiler comes the linker, whose job is to gather the pieces into an executable. It has its own complaints, and they look quite different.
The message names no line, because it is not about a line. Every line here is valid C++. The linker went looking for main, found nothing to start, and had no program to build. Change mian to main and run it again.
| The message says | What it almost always means |
|---|---|
expected ';' before ..., or expected ';' after expression | An instruction has no semicolon on the end. Look at the line named and at the line above it. |
'cout' was not declared in this scope, or use of undeclared identifier 'cout' | You wrote cout where you meant std::cout. |
'cout' is not a member of 'std', or use of undeclared identifier 'std' | #include <iostream> is missing. |
expected '}' | A curly bracket was opened and never closed. The message lands at the end of the file. |
missing terminating " character | A piece of text was opened with a quotation mark and not closed before the end of the line. |
undefined reference to 'main', or undefined symbols: _main | This one is the linker, not the compiler. There is no function called main, so check the spelling. |
The compiler reports eighteen errors from one file. What do you do first?
Read the first message and fix only that, then compile again. The errors after the first are frequently the compiler describing the wreckage rather than reporting eighteen separate problems, and any effort spent on them may be wasted. If the count does not fall much, that is genuine information too: it means the mistakes really were independent.