When the compiler says no
Learn
Three jobs before running
Building a C program is three jobs in a row:
- The preprocessor handles the lines that start with
#.#include <stdio.h>literally pastes in a file full of declarations, like the one that saysprintfexists and what it takes. - The compiler reads your code top to bottom and turns each function into machine code. It refuses anything it cannot make sense of: a missing
;, a name it has never seen, a function called with the wrong number of arguments. - The linker joins the pieces: your functions and the C library's. If you call a function that was promised but never written, this is where it fails.
The result is one block of machine code. Each function becomes a run of bytes at its own address in memory, and a call is a jump to that address. Filling in those addresses is the linker's job.
Only when all three succeed does anything run. So the error tells you which job failed, and that already narrows the search.
Learn
Reading an error
An error here looks like this:
main.c(5): `;' expected
printf("%d\n", lives);
^~~~~~main.c(5) is the file and the line. The ^ marks where the compiler was standing when it gave up. The catch: the missing ; is at the end of line 4. The compiler only noticed when line 5 started with something that cannot follow a value. An error points at where the compiler noticed, which is often just after the real mistake. Read the marked line, then the line above it.
Fix the first error first. One mistake can confuse the compiler into reporting more errors that vanish once the first is gone.
Learn
Declare before use
The compiler reads top to bottom, once. If main calls twice(4) and twice is written further down, at that moment the compiler has never heard of it, and it says twice is undeclared. Either move the function above main, or put a prototype near the top, a one-line promise of the name and types:
int twice(int n); // the body comes laterThat is what stdio.h is full of: prototypes for printf and friends. Their bodies live in the C library, and the linker connects your calls to them.
Try
Run it: a prototype at work
The example is already in the editor. Run it, change one thing, and run it again.
#include <stdio.h>
int twice(int n);
int main(void) {
printf("twice 21 is %d\n", twice(21));
return 0;
}
int twice(int n) {
return n * 2;
}
Break/fixFix the bug
Error on the wrong line
This game status program does not compile, and the error names line 5. Find the real mistake and fix it. It should print lives 3, coins 120.
#include <stdio.h>
int main(void) {
int lives = 3
int coins = 120;
printf("lives %d, coins %d\n", lives, coins);
return 0;
}
Break/fixFix the bug
Two errors, one cause
This prints a level, or it would. Run it: the compiler reports two errors. Fix the cause with one line. It should print Level 4.
int main(void) {
int level = 4;
printf("Level %d\n", level);
return 0;
}
Break/fixFix the bug
A function used too early
A shop adds 20 percent tax to a price in pence. add_tax is correct, but the program does not compile. Fix it without changing what add_tax does. It should print total 240.
#include <stdio.h>
int main(void) {
int total = add_tax(200);
printf("total %d\n", total);
return 0;
}
int add_tax(int pence) {
return pence + pence / 5;
}
PracticeExplain it
Promised but never written
This program gets past the compiler but fails to build with Unresolved: env.bonus. Which of the three jobs failed, and why?
#include <stdio.h>
int bonus(int score);
int main(void) {
printf("%d\n", bonus(50));
return 0;
}
int bonsu(int score) {
return score * 2;
}
Your turn
Playlist length in seconds
Write int track_seconds(int minutes, int seconds), which turns a track length like 3:25 into seconds, and put its body below main. Then make main print each track and the total:
3:25 is 205 seconds
4:10 is 250 seconds
2:57 is 177 seconds
total 632 secondsConstraint
- Write the body of track_seconds below main.
- Let the program work out the seconds; do not type the answers.
On your own. Hints open after your first check.
#include <stdio.h>
Passed
You can now
Keep going