gcc 编译链接与运行
更新时间:2026-08-26。本文是
languages/c/主题入门层第 1 篇。上一篇让程序跑了起来,这一篇把 gcc 这个工具讲透一点——它会陪你整个 C 生涯,值得花十分钟搞明白每个常用选项是干嘛的。
本文要回答的问题
gcc的常用选项分别是什么意思?-O2到底优化了什么?- "编译"是一个动作还是好几个动作?
- 多个
.c文件怎么一起编译?
一、从源码到可执行文件的四步
gcc hello.c 看起来一步到位,内部其实是四个阶段:

每一步都可以单独停住看中间产物:
gcc -E hello.c -o hello.i # 1. 预处理:看宏和头文件展开后的样子
gcc -S hello.c -o hello.s # 2. 编译:生成汇编(教学最常看这步)
gcc -c hello.c -o hello.o # 3. 汇编:生成目标文件(机器码)
gcc hello.o -o hello # 4. 链接:生成可执行文件把四个阶段卡住看汇编,是理解"C 代码到底变成什么"最快的方式——专家层与汇编、性能剖析衔接会大量用 gcc -S。
二、常用选项速查
| 选项 | 作用 | 什么时候用 |
|---|---|---|
-o 名字 | 指定输出文件名 | 每次编译 |
-O0 / -O1 / -O2 / -O3 | 优化等级,从"不优化"到"激进优化" | 学习 -O0,发布 -O2 |
-g | 生成调试符号 | 需要 gdb / perf 定位时 |
-Wall -Wextra | 打开常用警告 | 永远开着,能救命 |
-std=c11 / c17 | 指定语言标准 | 写新代码用 -std=c17 |
-I 目录 | 添加头文件搜索路径 | 用第三方库时 |
-l 名字 | 链接库(如 -lm 链数学库) | 用到 math.h 等库函数时 |
最稳的日常组合:
gcc -O0 -g -Wall -Wextra -std=c17 -o hello hello.c-Wall -Wextra 值得单独强调:它不修 bug,但会提前告诉你哪里有隐患——比如 if (x = 5) 写错成赋值,编译器会警告。新手期请无条件加上。
三、优化等级:-O0 和 -O2 差多少
同一段代码,-O2 和 -O0 生成的指令可能完全不同:
// sum.c:求和循环
#include <stdio.h>
int main(void) {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
printf("sum = %d\n", sum);
return 0;
}gcc -O0 -g -o sum0 sum.c
gcc -O2 -g -o sum2 sum.c-O2 下编译器可能直接把循环结果算出来、甚至整个循环优化掉——因为 sum 只被 printf 用到一次。这正是本站 demos/cpu-demo 的经典教学点:你以为热点的代码,-O2 下可能根本不存在了。所以剖析性能时,要么用 -O0 保留原始逻辑,要么剖析的就是"优化后的真实程序",两者含义完全不同。
四、多文件编译
工程代码不会只写一个文件。以"一个主程序 + 两个模块"为例:
// main.c
#include <stdio.h>
#include "calc.h"
int main(void) {
printf("%d\n", add(1, 2));
return 0;
}// calc.h —— 头文件:放声明
#ifndef CALC_H
#define CALC_H
int add(int a, int b);
#endif// calc.c —— 源文件:放定义
#include "calc.h"
int add(int a, int b) { return a + b; }gcc -O0 -g -Wall -o prog main.c calc.cgcc 一次性把两个 .c 编译再链接。calc.h 里那三行 #ifndef / #define / #endif 叫头文件守卫,防止同一个头文件被包含两次——新手常忽略,多文件工程必加。
五、两个容易懵的错误
undefined reference to 'add':这是链接期错误,意思是"声明了但没找到定义"。多半是 calc.c 没参与编译(漏写在命令里),或编译了但没链接。注意它和 implicit declaration(编译期错误,没声明)是不同的错误。
main 重复定义:多个 .c 文件里各写了一个 main。整个程序只能有一个 main,模块文件不该写 main。
六、与本站主线衔接
- 编译优化与
-O2消除循环,见 L4 编译器选项; - 四步流程在可执行文件里的落点(段、符号表),见专家层 编译、链接与 ELF;
- 多文件工程的规模化管理,交给 Makefile(高手层)。
一句话总结
gcc 把源码走四步变成可执行文件——预处理、编译、汇编、链接,-Wall -Wextra 无条件开、-O0 保留真相、-O2 是优化后的另一个世界;多文件编译就是"所有 .c 一起给 gcc",头文件守卫别忘写。
上一篇:环境搭建与第一个程序 下一篇:编辑器配置