应组合使用_WIN32、__linux__、__APPLE__等宏并加防御性判断,因单靠_WIN32或__linux__易误判(如WSL、交叉编译、IDE预定义等场景),须分层判断、显式覆盖、强制报错未支持平台。

直接结论:用 _WIN32 判断 Windows(含 64 位),用 __linux__ 判断 Linux;但别只信一个,得组合用、加防御、防误判。
为什么不能只靠 _WIN32 或 __linux__?
这两个宏看似简单,实际陷阱不少:_WIN32 在 MinGW、MSVC、Clang/Windows 下都定义,但 __linux__ 在 WSL、Docker 容器、交叉编译环境里可能被意外启用(比如某些嵌入式工具链会模拟它);而 macOS 完全不定义这两个——它用的是 __APPLE__。更麻烦的是,有些 IDE 或构建系统(如 CMake + Ninja)会在非目标平台预定义错误宏,导致编译时“看起来是 Linux”,实际跑不起来。
#ifdef _WIN32 和 #ifdef __linux__ 怎么安全配对?
必须明确:它们不是互斥的“开关”,而是独立的“特征标记”。正确写法是分层判断,优先排除共存可能,并显式覆盖默认分支:
#ifdef _WIN32
// Windows 专用路径(含 MSVC / MinGW / Clang-cl)
#include
#define PATH_SEP '\\'
#elif defined(__linux__)
// 真实 Linux(不是 WSL2 的“Linux 内核但用户态是 Windows”混淆场景)
#include
#define PATH_SEP '/'
#elif defined(__APPLE__)
// macOS(注意:__APPLE__ 不隐含 __linux__,也不隐含 _WIN32)
#include
#define PATH_SEP '/'
#else
#error "Unsupported platform"
#endif
- 用
#elif defined(__linux__)而非#ifdef __linux__,避免和前面的_WIN32形成逻辑断裂 - 永远补上
#else #error,强制暴露未覆盖平台,比静默走错分支更早发现问题 - 不要写
#ifdef _WIN32 || __linux__—— 预处理器不支持逻辑运算符在#if外使用
跨平台宏判断常踩的三个坑
实际项目里,90% 的平台判断 bug 来自这三处:
立即学习“C++免费学习笔记(深入)”;
-
_WIN64和_WIN32并非二选一:_WIN32在所有 Windows 编译器(32/64 位)下都定义;_WIN64仅在 64 位目标下定义。想区分位数,得写#ifdef _WIN64,而不是假设_WIN32意味着 32 位 -
__linux__是双下划线开头+双下划线结尾,少一个下划线(如__linux)就失效;且它不保证__gnu_linux__或__ANDROID__同时存在——Android NDK 默认定义__linux__,但你要用 Android 特有 API,还得额外检查__ANDROID__ - 头文件包含顺序影响宏可见性:如果某个第三方头(如
)内部重定义了__linux__,而你又在它之后写判断,结果就不可控。解决方案是——所有平台判断宏放在最顶部,甚至单独抽成platform.h,并在每个源文件第一行#include
真正难的不是记住哪几个宏,而是理解每个宏背后代表的**编译器行为**而非操作系统名称。比如 _WIN32 其实表示“当前编译器声称支持 Win32 API”,哪怕你在 Linux 上用 MinGW-w64 交叉编译,它也照样定义——这时候你得结合 __MINGW32__ 或 __CYGWIN__ 进一步细分。跨平台从来不是贴标签,而是层层验证。











