c++oding="utf-8" ?>
必须显式加-stdlib=libc++,否则clang++默认链接libstdc++;还需确保头文件、libc++.so、libc++abi.so三者路径正确且版本对齐。

直接用 libc++ 编译 C++ 程序,关键不是“能不能”,而是 clang 是否链接了 libc++ 而不是系统默认的 libstdc++ —— 默认情况下它不会,必须显式指定。
clang++ 默认链接的是 libstdc++,不是 libc++
即使你已经从源码构建并安装了 LLVM + libc++,clang++ 仍会优先找系统 /usr/lib/x86_64-linux-gnu/libstdc++.so(或 macOS 上的 libstdc++.dylib),除非你明确告诉它换一个。这是最容易踩的坑:你以为用了 libc++,其实还是 libstdc++。
- 验证方式:
clang++ -stdlib=libc++ -v hello.cpp 2>&1 | grep "selected",看输出里是否含libc++.so或libc++.dylib - 不加
-stdlib=libc++时,clang++实际调用的是--stdlib=libstdc++(隐式) - 仅安装 libc++ 头文件(
include/c++/v1/)不够,运行时库(libc++.so或libc++.dylib)也必须可用且能被链接器找到
编译第一个 libc++ 示例程序的三步实操
假设你已通过源码构建并安装了 LLVM(含 libc++),安装路径为 /opt/llvm(常见于自建构建):
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 确保头文件路径可访问:
clang++ -I/opt/llvm/include/c++/v1/(v1是 libc++ 的标准头目录名) - 链接 libc++ 运行时:
-L/opt/llvm/lib -lc++ -lc++abi(libc++abi是必需依赖,不能省) - 禁用 libstdc++ 干扰:
-nostdlib++(可选但推荐,避免链接器偷偷拉入 libstdc++)
完整命令示例:
clang++ -std=c++17 -I/opt/llvm/include/c++/v1/ \ -L/opt/llvm/lib -lc++ -lc++abi -nostdlib++ \ hello.cpp -o hello
其中 hello.cpp 可以只写一行:#include <string> int main() { std::string s = "hello"; }</string> —— libc++ 对 std::string 的实现与 libstdc++ 不同,能跑通就说明生效了。
常见错误:undefined reference to `operator new(unsigned long)`
这个错误几乎总是因为漏了 -lc++abi 或没配好 ABI 库路径。libc++ 不提供内存分配符的底层实现,全靠 libc++abi 提供 operator new、__cxa_throw 等。不同构建方式下,libc++abi 可能被静态链接进 libc++.so,也可能独立存在:
- 用 CMake 构建 llvm-project 时,默认启用
LLVM_ENABLE_LIBCXXABI=ON,会生成独立的libc++abi.so - 若你关闭了该选项,
libc++.so内部已包含 ABI 符号,此时可省略-lc++abi,但需确认readelf -d /opt/llvm/lib/libc++.so | grep NEEDED不含libc++abi - macOS 上通常用
libc++abi.dylib,路径常在/usr/lib/,但自建版本建议统一走-L指定
真正麻烦的从来不是“怎么写命令”,而是路径、ABI 依赖、头文件版本和运行时库版本四者是否严格对齐——差一个 patch 版本,std::vector 的内存布局可能就不兼容。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










