最可靠的方式是优先使用__LP64__和_WIN64宏判断,因它们在预处理阶段即确定、无运行时干扰:GCC/Clang在LP64系统(如Linux/macOS)定义__LP64__,MSVC在64位Windows下定义_WIN64;二者不重叠且覆盖主流平台,但MinGW等工具链需回退至sizeof(void*)==8作编译期兜底。
__LP64__ 和 _WIN64 判断 64 位系统最可靠直接看宏定义比查 sizeof(void*) 更早、更确定——编译器在预处理阶段就决定了这些宏,不会受运行时环境干扰。GCC/Clang 在 LP64 模型(如 Linux/macOS)下定义 __LP64__;MSVC 在 64 位 Windows 下定义 _WIN64。两者不重叠,也不覆盖所有平台,但覆盖了主流场景。
__LP64__:Linux x86_64、macOS ARM64/x86_64 都有,但 Windows MinGW-w64 默认不定义(除非显式加 -m64 且启用 LP64)_WIN64:仅 MSVC 和兼容它的工具链(如 clang-cl)定义,MinGW 不定义__x86_64__ 或 __aarch64__ 替代——它们判断的是 CPU 架构,不是“系统位数”;ARM32 上跑 64 位 kernel 时仍可能是 32 位用户态同一个 Windows 系统,用 MSVC 编译时能用 _WIN64,换 MinGW 就失效。MinGW 默认走 ILP32 模型,即使目标是 x86_64,也只定义 __x86_64__,不定义 _WIN64。这时候得靠 sizeof(void*) == 8 回退,但必须确保它出现在编译期常量上下文中(比如 static_assert 或模板参数)。
#ifdef _WIN64 → 64 位 Windows 用户态#ifdef __x86_64__ 仅表示目标架构,需配合 __MINGW64_VERSION_MAJOR(如果可用)或直接测 sizeof(void*)
sizeof(void*) 是最通用的兜底方案,但有编译期限制当宏不可靠或跨平台抽象层需要统一逻辑时,sizeof(void*) 是最终依据。但它不能用在预处理器条件里(#if sizeof(void*) == 8 会报错),只能用于 constexpr、static_assert 或模板特化。
static_assert(sizeof(void*) == 8, "64-bit expected");
#if sizeof(void*) == 8 → 预处理器不认识 sizeof
template<int sizeof> struct is_64bit;</int>,但不如宏直观void* 定义都不稳定,这时宏仍是唯一选择INTPTR_MAX 或 SIZE_MAX
这些是头文件里的常量,值由 stdint.h 或 cstdint 提供,但它们本身是编译结果,不是编译器内置宏。如果标准库头文件被裁剪、或用了非标准实现(比如某些 RTOS),INTPTR_MAX 可能未定义,或者值被硬编码成 32 位——它反映的是 ABI,不是编译器对当前平台的判断。
立即学习“C++免费学习笔记(深入)”;
#include <cstdint> 后才能用 INTPTR_MAX,而宏判断无需 includeINTPTR_MAX == INT64_MAX 在多数 64 位系统成立,但有些 32 位系统(如某些 DSP)也定义为 INT64_MAX,只为支持大地址运算sizeof(void*) 不一定同步:理论上可以有 sizeof(void*) == 4 但 INTPTR_MAX == 0x7fffffffffffffff(极少见,但标准允许)sizeof(void*),最后才考虑 INTPTR_MAX。最容易被忽略的是 MinGW 和 MSVC 在 Windows 上的行为差异——同一套代码,在 Visual Studio 里走 _WIN64 分支,用 MinGW 编译却进了 32 位逻辑,连 warning 都没有。