clang 支持 -c 选项,用于只编译不链接,生成 .o 目标文件;它兼容 gcc 习惯,但需配合 -o 指定输出,否则可能静默失效;-c、-s、-e 分别停在编译后、汇编前、预处理后阶段。

-c 参数不是 Clang 的标准选项,它根本不存在。
Clang 没有 -c 这个参数
常见混淆来源是 GCC 或某些旧文档误写。Clang 正确的「只编译不链接」选项是 -c —— 等等,这看起来矛盾?其实不矛盾:Clang 确实支持 -c,但它**不是“-c”参数本身起作用,而是 Clang 兼容 GCC 的命令行习惯,把 -c 当作一个有效开关来识别**。但必须明确:
-
-c在 Clang 中仅表示「停止在编译阶段,输出目标文件(.o)」,不调用链接器 - 它不控制预处理、不启用调试、不改变语言标准——这些全靠其他选项
- 如果你在 clang 命令里写了
-c却没生成 .o 文件,大概率是因为路径、权限或输入文件名错误,而不是-c失效
什么时候该用 -c
典型场景就是构建多文件项目,需要分步编译再统一链接:
- 你有
main.c和utils.c,想先各自编译成目标文件:clang -c main.c -o main.oclang -c utils.c -o utils.o - 之后再链接:
clang main.o utils.o -o program - 避免重复编译:修改了
utils.c,只需重跑clang -c utils.c -o utils.o,不用碰main.o
注意:如果漏掉 -o,Clang 默认输出到 a.out(即使加了 -c),但这是个陷阱——-c 要求输出目标文件,而没指定 -o 时,Clang 会静默忽略 -c 并尝试链接,报错类似 ld: can't link because no input files。
Clang 22.1.3 Windows 64 位历史版本安装包,适合旧项目兼容、LLVM/Clang 工具链回退、编译行为对比、链接问题复现和 C/C++ 构建环境维护。
-c 和 -E、-S 的区别必须分清
这三个都是“停在某阶段”的开关,但阶段不同、输出不同、用途完全不同:
-
-c:停在**编译后、汇编后、链接前** → 输出.o(机器码目标文件) -
-S:停在**编译后、汇编前** → 输出.s(人类可读的汇编代码) -
-E:停在**预处理后、编译前** → 输出.i(展开宏、插入头文件后的 C 代码,带或不带注释取决于是否加-C)
比如你想看宏展开效果,用 -E;想检查生成的汇编质量,用 -S;想进 Makefile 分离编译流程,才用 -c。混用会导致输出文件类型和预期不符,尤其在自动化脚本里容易出错。
真正容易被忽略的是:Clang 对 -c 的依赖非常强——它不光影响输出,还隐式决定是否启用某些默认行为,比如是否查找 main 符号、是否链接 crt0。一旦加了 -c,后续命令里哪怕漏掉一个 -o,整个构建链就断在不可见的地方。










