加-c参数即可只编译不链接,clang默认全程执行至生成可执行文件;-c使clang停在汇编阶段输出.o文件,不解析符号、不链接库,漏掉则导致undefined reference等链接错误。

加 -c 参数即可,这是最直接、最可靠的方式;漏掉它,clang 默认会走完全部流程,直接输出可执行文件,而不是你想要的 .o。
为什么 clang 不加 -c 就不是“只编译”
clang 和 clang++ 默认行为是“全流程编译+链接”,即从预处理、编译、汇编一路干到生成可执行文件(如 a.out 或你用 -o 指定的文件)。它不区分“编译阶段”和“链接阶段”,除非你明确告诉它停在哪儿。
常见错误现象:
- 写了
clang++ main.cpp -o main.o,以为生成了目标文件,结果发现main.o实际是可执行文件(file main.o会显示 ELF executable) - 多个源文件一起编译时漏
-c,clang 尝试把所有.cpp一次性链接,报一堆undefined reference
根本原因:没有 -c,clang 就不会生成中间的目标文件,而是跳过目标文件这层,直接拿编译结果去链接。
clang -c 的实际效果和典型用法
-c 的作用非常明确:只执行到汇编阶段,输出 .o(或 .obj),不做任何符号解析、库查找或地址重定位。它产出的是 relocatable object file,里面可能有未定义符号(比如 _printf、_main),这完全正常。
实操建议:
- 单文件编译:
clang++ -c main.cpp -o main.o - 多文件分别编译:
clang++ -c a.cpp -o a.o && clang++ -c b.cpp -o b.o - 想看中间产物是否符合预期,用
nm a.o查未定义符号:nm -u a.o列出所有 undefined symbol - 若需保留调试信息,加上
-g:clang++ -g -c main.cpp -o main.o
链接时容易忽略的 C++ 运行时依赖
单独用 -c 编译 C++ 文件没问题,但后续链接时如果忘了链接标准库,会立刻报错。例如:
clang++ a.o b.o -o program → 很可能失败,提示 undefined reference to 'operator new(unsigned long)' 或类似 C++ 特有符号
这是因为 .o 里调用了 STL、异常、RTTI 等,需要显式链接 C++ 运行时:
- Linux/macOS 上常用:
-lstdc++或更现代的-lc++ - 完整链接命令示例:
clang++ a.o b.o -lstdc++ -o program - 注意:C 文件用
clang编译 + 链接时通常不需要额外指定 C 库,但 C++ 一定需要
真正容易被忽略的点在于:-c 只管“停住”,不管“干净”。它生成的 .o 是合法的、可链接的,但链接能否成功,取决于你后续是否补全了所有依赖——尤其是 C++ 这种隐式依赖极多的语言。

















