Brainlag
  1. C
  2. Foundations
02/38 lessons

When the compiler says no

25 min5 exercises

Learn

Three jobs before running

Building a C program is three jobs in a row:

  1. The preprocessor handles the lines that start with #. #include <stdio.h> literally pastes in a file full of declarations, like the one that says printf exists and what it takes.
  2. 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.
  3. 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:

C
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:

C
int twice(int n);   // the body comes later

That 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.

example.c to run
#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.

exercise_1.c to run
#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.

exercise_2.c to run
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.

exercise_3.c to run
#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?

exercise_4.c
#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:

Output
3:25 is 205 seconds
4:10 is 250 seconds
2:57 is 177 seconds
total 632 seconds

Constraint

  • 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.

exercise_5.c to run
#include <stdio.h>
Step 1 of 9
C, 32-bit: int and pointers are 4 bytes

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.