_WIN32和__linux__是最可靠的操作系统判断依据:_WIN32覆盖所有Windows架构,__linux__是Linux标准宏,大小写与双下划线不可错,且需优先于__ANDROID__判断;其他宏如__unix__、__GNUC__、WIN32等易误判或不标准。

_WIN32 和 __linux__ 是最可靠、最直接的判断依据,其他宏(如 __unix__、linux、_WINDOWS)要么不标准,要么易误判。
用 _WIN32 判断 Windows,不是 _WIN64 或 WIN32
MSVC、Clang on Windows、MinGW 全部定义 _WIN32,它覆盖所有 Windows 架构(x86/x64/ARM64)。而 _WIN64 只在 64 位下定义,WIN32(无下划线)不是标准宏,某些旧项目可能自定义,但编译器不保证定义。
- 正确写法:
#ifdef _WIN32—— 安全、通用、无需额外头文件 - 错误写法:
#ifdef WIN32或#ifdef __WIN32__—— 不被 Clang/GCC/MSVC 统一支持,容易漏编译 - 别用
_WIN64单独判断 Windows:它在 32 位 Windows 下不定义,会漏掉整个平台
用 __linux__ 判断 Linux,注意双下划线和大小写
__linux__ 是 GCC 和 Clang 在 Linux 系统上的标准预定义宏,必须是两个下划线 + 小写 linux + 两个下划线。常见错误包括写成 linux、LINUX、__Linux__ 或 __gnu_linux__(后者已弃用且非必需)。
- Android 也定义
__linux__,但同时定义__ANDROID__;如果代码需区分 Android,__ANDROID__必须放在__linux__之前判断,否则会被“吞掉” -
__unix__不能替代__linux__:它在 macOS、FreeBSD、Solaris 下也都定义,单独用会导致 macOS 代码误入 Linux 分支 - 不要依赖
__GNUC__判断 Linux:Clang 默认也定义它,纯属误导
避免嵌套过深,优先用扁平化结构
实际工程中,Windows/Linux 二分足够时,别强行引入 __APPLE__ 或 __ANDROID__ 增加复杂度。一个清晰、可读、易维护的结构比“理论上全覆盖”更重要。
立即学习“C++免费学习笔记(深入)”;
- 推荐结构:
#ifdef _WIN32 // Windows-only code: e.g., Sleep(), .dll loading, windows.h #elif defined(__linux__) // Linux-only code: e.g., usleep(), .so dlopen(), unistd.h #else #error "Unsupported platform" #endif
- 若后续要加 macOS 支持,再扩展为三层;但此时必须包含
<TargetConditionals.h>并用TARGET_OS_MAC区分 macOS/iOS,不能只靠__APPLE__ - CMake 中可通过
add_compile_definitions()预定义统一宏(如PLATFORM_WINDOWS),但底层仍应基于原生宏判断,避免二次抽象失真
真正容易被忽略的是 Clang 对 __GNUC__ 的伪装行为——它让很多只检查 __GNUC__ 的 Linux 分支在 macOS 上意外触发,结果因缺少 <sys/stat.h> 等头文件而编译失败。所以平台判断永远以操作系统宏为第一优先级,编译器宏仅用于微调内部实现(如 attribute 写法),不可混用。


















