Exercise 1-1. Run the “hello, world” program on your system. Experiment with leaving out parts of the program to see what error messages you get.
This page covers the error-experimentation part of Exercise 1-1. The baseline working program is in Exercise 1-1a. Here we deliberately break it five different ways — and more importantly, learn to read what gcc tells us.
Approach: gcc Errors Are Instructions, Not Obstacles
Most beginners stare at a wall of red error text, panic, and start randomly deleting or changing code. That is exactly the wrong response. gcc’s error messages follow a precise format that tells you the filename, line number, column number, and the nature of the problem. Once you learn to read that format, the errors become the fastest path to a fix.
The format is always:
filename.c:line:column: severity: message
Where severity is either error (compilation halts — no binary is produced) or warning (compilation may succeed, but something suspicious was detected). We start from the working hello world program and introduce one deliberate mistake at a time.
The Working Baseline
/* Compile: gcc -ansi -Wall hello.c -o hello */
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
Save this as hello.c. Confirm it compiles and prints hello, world before experimenting with the broken versions below.
Error 1: Missing Semicolon
Remove the semicolon from the end of the printf line:
#include <stdio.h>
int main(void)
{
printf("hello, world\n") /* semicolon removed */
return 0;
}
hello.c: In function 'main':
hello.c:6:5: error: expected ';' before 'return'
6 | return 0;
| ^~~~~~
Reading the message: gcc points to line 6, column 5 — the word return. Why does it point to return and not to the missing semicolon on line 5? Because the C parser is greedy: it keeps consuming tokens until something breaks the grammar. It only realises a semicolon is missing when it sees a keyword (return) where a semicolon should have appeared. The reported line is where gcc noticed the problem; the actual problem often lives one line above. When the flagged line looks syntactically correct, always check the line before it.
Error 2: Missing #include (Undeclared Function)
Remove the #include <stdio.h> line entirely:
int main(void)
{
printf("hello, world\n");
return 0;
}
hello.c: In function 'main':
hello.c:3:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
3 | printf("hello, world\n");
| ^~~~~~
hello.c:3:5: note: include '<stdio.h>' or provide a declaration of 'printf'
Reading the message: gcc sees a call to printf but has no declaration for it. In C89/ANSI C, calling an undeclared function is assumed to return int — the “implicit declaration” gcc is warning about. Notice the note: line: gcc tells you exactly what to add. In C99 and later, implicit function declarations are outright errors. Always treat this warning as a real error: fix the missing header and never ship code with it in place.
Error 3: Typo in a Function Name
Misspell printf as prinft:
#include <stdio.h>
int main(void)
{
prinft("hello, world\n"); /* typo: prinft instead of printf */
return 0;
}
hello.c: In function 'main':
hello.c:5:5: warning: implicit declaration of function 'prinft' [-Wimplicit-function-declaration]
5 | prinft("hello, world\n");
| ^~~~~~
hello.c:5:5: note: did you mean 'printf'?
5 | prinft("hello, world\n");
| ^~~~~~
| printf
Reading the message: Because prinft is not declared anywhere — not in <stdio.h>, not in your code — gcc treats it as an implicit declaration. Modern gcc goes further and suggests a correction: “did you mean ‘printf’?” using a similarity algorithm to find known identifiers close to what you typed. This is a genuinely useful feature. The program will likely crash at runtime because the implicit assumption about the function’s return type and calling convention will be wrong. Treat “implicit declaration” warnings as hard errors during development.
Error 4: Missing Closing Brace
Delete the closing } of main:
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
/* closing brace deleted */
hello.c: In function 'main':
hello.c:6:13: error: expected '}' at end of input
6 | return 0;
| ^
Reading the message: The parser consumed the entire file looking for a } to close the function body and never found one. It reports the error at the last token it saw before running out of file — the semicolon after 0 on line 6. For this small program the fix is obvious. In a larger program with many nested braces this error can be ambiguous: the actual missing brace could be anywhere. Use an editor with brace-matching highlighting (VS Code does this with Ctrl+Shift+\ on the relevant brace) to pinpoint the gap.
Error 5: Unterminated String Literal
Replace the closing double-quote of the string with a single-quote:
#include <stdio.h>
int main(void)
{
printf("hello, world\n'); /* wrong: single-quote closes nothing */
return 0;
}
hello.c:5:12: warning: missing terminating " character
5 | printf("hello, world\n');
| ^
hello.c:5:5: error: missing terminating " character
5 | printf("hello, world\n');
| ^
hello.c:6:5: error: expected expression before 'return'
6 | return 0;
| ^~~~~~
hello.c:7:1: error: expected ';' before '}' token
7 | }
| ^
Reading the message: A single unclosed string literal triggers a cascade of four messages. The compiler opens the string at the " on line 5, then keeps reading — swallowing the single-quote, the right parenthesis, and the semicolon as characters inside the string — until the newline forces it to give up (C string literals cannot span lines without a backslash continuation). Everything from line 6 onward is then misinterpreted, producing three more errors that are pure consequences of the first. This is the most important diagnostic skill: when you see a flood of errors, fix only the first one and recompile. The flood usually collapses to zero.
Errors vs. Warnings: What Is the Difference?
gcc uses two severity levels:
- error — Compilation halts. No output binary is produced. You must fix this before the program can run.
- warning — Compilation continues and a binary may be produced. There is a suspicious construct that is likely a bug or portability problem. The program might appear to run, but the behaviour is undefined or implementation-dependent.
A common beginner mistake is to ignore warnings because “the program compiled.” Warnings in C are rarely benign. An implicit function declaration warning, for example, can produce a program that corrupts memory at runtime because the assumed return type and calling convention are wrong.
The -Wall Flag
-Wall stands for “enable all common warnings.” It is not literally all warnings gcc can emit — there are additional groups like -Wextra and -Wpedantic — but it enables the most important set. Always compile with -Wall while learning C. Many textbook examples and online snippets omit it; add it anyway. Catching problems at compile time is always cheaper than debugging a running program.
Recommended compile command for all K&R Chapter 1 exercises:
gcc -ansi -Wall -Wextra hello.c -o hello
-ansi enforces the C89 standard that K&R 2nd edition was written for, which keeps your code consistent with the book.
Compile and Run (Working Version)
gcc -ansi -Wall hello.c -o hello
./hello
hello, world
What This Exercise Teaches
- gcc’s error format —
file:line:column: severity: message— always read the location before looking at the code - The reported line is where gcc noticed the problem; the actual mistake often lives one line earlier (classic with missing semicolons)
- The first error in a cascade is almost always the root cause; fix it first, then recompile before addressing the rest
- The difference between
error(fatal, no binary) andwarning(suspicious, must not be ignored) - The purpose of
-Wall: surface problems statically, before the program ever runs
Set Up Your C Environment
To reproduce these error messages yourself, you need gcc installed. If you haven’t set up C on your machine yet:
- Complete C Development Environment Setup — full beginner guide
- Install GCC on Windows 11
- Install GCC on macOS
- Install GCC on Ubuntu/Linux
- VS Code for C Programming — recommended editor with inline error highlighting
- Best Online C Compilers — compile in your browser with no installation
← Exercise 1-1b |
Chapter 1 Solutions |
Exercise 1-2 →
Book:
The C Programming Language, 2nd Ed — Kernighan & Ritchie