Session 1 — Compilation Basics: Instructor Print Guide
Instructor material — not student-facing
Single-page print reference: all demo files and terminal commands in order.
Setup
cd ~/lecture/session1/
Demo Files
hello.c
#include <stdio.h>
int main(void)
{
printf("Hello, toolchain!\n");
return 0;
}
util.h
#ifndef UTIL_H
#define UTIL_H
int compare(int a, int b);
#endif
util.c
#include "util.h"
int compare(int a, int b)
{
if (a == b) return 0;
if (a < b) return 1;
return -1;
}
main.c
#include "util.h"
#define N 20
#define M 35
int main(void)
{
int ret_value = compare(N, M);
return ret_value;
}
a.h (broken — no guard)
/* a.h — NO header guard on purpose */
const int g_variable = 50;
b.h (broken — includes a.h)
/* b.h — includes a.h */
#include "a.h"
int func(void)
{
return g_variable;
}
main_broken.c
#include "a.h"
#include "b.h"
int main(void)
{
int var = g_variable;
return var + func();
}
a_fixed.h
#ifndef A_H
#define A_H
const int g_variable = 50;
#endif
b_fixed.h
#ifndef B_H
#define B_H
#include "a_fixed.h"
int func(void)
{
return g_variable;
}
#endif
main_fixed.c
#include "a_fixed.h"
#include "b_fixed.h"
int main(void)
{
int var = g_variable;
return var + func();
}
1.1 — Motivation (10 min)
Show the “Program vs. Software” table. Ask:
“Who has worked on a project with more than 3 files?” “How did you compile it? Did you type
gcccommands by hand?“
1.2 — Preprocessing (15 min)
Warning
▶ Wooclap Q1
Fire before showing any terminal output.
cat util.h
cat main.c
# Show what the preprocessor does
gcc -E main.c | less
# #include is literally copy-paste, #define is text replacement
1.3 — From Source to Binary (30 min)
# 1. Preprocessing
gcc -E main.c -o main.i
wc -l main.c main.i # show how much the preprocessor adds
# 2. AST (brief, don't dwell)
clang -Xclang -ast-dump -fsyntax-only main.c 2>/dev/null | head -30
# 3. Intermediate representation
clang -S -emit-llvm main.c -o main.ll
cat main.ll # ideal machine, no register limits
# 4. Assembly
gcc -S main.c -o main.s
cat main.s # real registers (rax, rdi, rsi)
# 5. Object file
gcc -c main.c -o main.o
hexdump -C main.o | head -20 # just bytes
nm main.o # T = defined, U = undefined
Warning
▶ Wooclap Q2
Fire after showing nm main.o, before running nm util.o.
# 6. Linking
gcc -c util.c -o util.o
nm util.o # compare is T here
gcc main.o util.o -o program
nm program # all symbols resolved
./program ; echo $?
1.4 — Common Errors (15 min)
# Error 1 — Missing include / undeclared identifier
# Remove #include "util.h" from main.c
gcc -c main.c
# → "implicit declaration" or "undeclared identifier"
# Fix: add the include back
# Error 2 — Undefined symbol (linker error)
gcc main.o
# → "Undefined symbols: _compare"
Warning
▶ Wooclap Q3
Show the linker error on the projector, fire before explaining it.
/usr/bin/ld: main.o: undefined reference to symbol 'compare' # Fix: link with util.o
gcc main.o util.o -o program
1.5 — Include Guards (15 min)
# Show multiple inclusion error
cat a.h
cat b.h
cat main_broken.c
gcc main_broken.c # → redefinition error
# Show preprocessed output to explain WHY
gcc -E main_broken.c # g_variable defined twice!
# Fix with header guards
cat a_fixed.h # with #ifndef/#define/#endif
gcc main_fixed.c # compiles!
Show both styles: #ifndef guards and #pragma once.
1.6 — Quick Recap (5 min)
Draw on board:
.c → [preprocessor] → .i → [compiler] → .s → [assembler] → .o → [linker] → executable
gcc -E gcc -S as/gcc -c gcc
“If you see
undefined reference to X, which step failed?”