std::filesystem 是跨平台路径操作的唯一靠谱选择,应使用 std::filesystem::path 构造路径并用 / 拼接,避免字符串拼接导致的转义和分隔符错误。

用 std::filesystem 替代手写路径拼接
Windows 用反斜杠 \,Linux 用正斜杠 /,自己拼字符串早晚出错。C++17 的 std::filesystem 是跨平台路径操作的唯一靠谱选择。
常见错误现象:"data\config.txt" 在 Linux 下变成 dataconfig.txt(因为 \c 被解释为转义字符);或路径存在但 std::ifstream 打不开,实际是分隔符不匹配。
- 始终用
std::filesystem::path构造路径:std::filesystem::path("data") / "config.txt",它会自动适配平台分隔符 - 避免把路径当
std::string拼接,尤其别用+或+= - 检查编译器支持:GCC ≥ 8、Clang ≥ 9、MSVC ≥ 2017 都行,但需开
-std=c++17且 GCC/Clang 要链接-lstdc++fs(MSVC 不需要)
条件编译只用于系统差异,别用来“猜”行为
不是所有差异都该用 #ifdef _WIN32 拦住,比如文件权限、线程栈大小、信号机制这些底层差异,靠宏掩盖反而让 bug 更隐蔽。
使用场景:仅当标准库不覆盖、且行为不可统一时才用——比如 Windows 没有 fork(),Linux 没有 WaitForSingleObject();或者需要调用 GetLastError() vs errno。
立即学习“C++免费学习笔记(深入)”;
- 优先查
std::error_code和std::system_error,它们已封装了多数系统错误映射 - 避免写
#ifdef _WIN32 ... #else ... #endif包裹一整段业务逻辑,那说明设计没抽象干净 - 若真要调系统 API,把平台相关代码隔离到单独的 .cpp 文件(如
os_win.cpp/os_linux.cpp),头文件只暴露统一接口
文件编码和换行符必须显式处理
Windows 记事本默认保存为 UTF-16LE + CRLF,Linux 工具链默认 UTF-8 + LF。C++ 标准库读文本文件时不自动转码也不修换行,直接导致解析失败或乱码。
常见错误现象:配置文件在 Windows 下能读,在 Linux 下第一行就 std::getline() 返回空;或中文路径传给 std::fstream 失败(UTF-8 字节流被当 Latin-1 解释)。
- 源码文件统一存为 UTF-8 无 BOM(编辑器可设),避免
u8"中文"在不同平台解码不一致 - 读写文本文件时,不要依赖默认 locale,显式用
std::codecvt_utf8(C++11/17)或 C++20 的std::from_chars/std::to_chars处理编码 - 换行符一律按
\n处理,写文件时用\n,读时用std::getline()(它自动跳过\r\n或\n)
静态链接 libstdc++ 或 libc++ 避免运行时冲突
Linux 发行版 glibc 版本碎片化严重,Windows 又没有全局 C++ 运行时共享机制。动态链接标准库,很容易在客户机器上因缺少 libstdc++.so.6 或版本不匹配而崩溃。
性能 / 兼容性影响:静态链接增大二进制体积(约 1–2MB),但彻底消除依赖问题;对嵌入式或 Docker 场景几乎是必须的。
- Linux 编译加
-static-libstdc++ -static-libgcc(GCC)或-static(Clang + libc++) - Windows MSVC 默认静态链接
/MT,别用/MD(否则要部署vcruntime140.dll等) - 注意:静态链接不能解决第三方动态库(如 Qt、Boost)的依赖,那些得单独处理
最麻烦的从来不是语法怎么写,而是你写的那段“看起来没问题”的路径处理或错误检查,在另一台机器上根本没走你预想的分支。跨平台不是让代码跑起来,是让它的行为在两套系统里严格一致。











