最直接可靠的方式是用sizeof(void*)在编译期判断指针大小:值为4表示32位目标,8表示64位目标;它反映当前程序的ABI位宽而非宿主系统能力,零开销、跨平台、不依赖运行时API。

用 sizeof(void*) 是最直接可靠的方式
编译时就能确定指针大小,它直接反映目标平台的地址宽度。32 位系统上 sizeof(void*) == 4,64 位系统上 sizeof(void*) == 8。这不是运行时探测,而是编译期常量,零开销、无歧义。
注意:这判断的是「当前程序被编译为哪种模式」,不是宿主系统的原生能力。比如在 Windows 10 x64 上运行 32 位程序,sizeof(void*) 仍是 4。
- 不要用
sizeof(int)或sizeof(long)—— 它们在不同平台 ABI 下变化大(如 Linux x64 中long是 8 字节,Windows x64 中仍是 4 字节) - 宏
__LP64__、_WIN64、__x86_64__等也可用,但属于编译器/平台特定,可移植性不如sizeof(void*) - 若需区分“系统能跑 64 位程序”还是“当前进程是 64 位”,后者才该用
sizeof(void*);前者得调系统 API(如 Windows 的IsWow64Process)
Windows 下用 GetNativeSystemInfo 判断系统原生架构
当真要确认 OS 本身是否为 64 位(例如决定是否部署 64 位插件),必须查系统信息,而非当前进程。Windows 提供 GetNativeSystemInfo,它返回的是物理系统的 SYSTEM_INFO,不受 Wow64 重定向影响。
关键点:必须链接 kernel32.lib,且在 32 位进程中调用它,才能看出系统是否真支持 64 位。
立即学习“C++免费学习笔记(深入)”;
- 先调
GetNativeSystemInfo,再检查lpMinimumApplicationAddress或dwPageSize没用——真正看的是dwProcessorType是否为PROCESSOR_AMD64或PROCESSOR_IA64 - 更稳妥的做法是结合
IsWow64Process(GetCurrentProcess(), &bIsWow64):如果返回TRUE,说明当前是 32 位进程跑在 64 位系统上 - 别依赖
GetSystemInfo—— 在 Wow64 进程中它返回的是模拟层信息,不是原生系统能力
Linux/macOS 下读取 /proc/cpuinfo 或 uname -m 不推荐用于程序逻辑
虽然命令行执行 uname -m 能看到 x86_64 或 i686,但把它嵌入 C++ 程序去 fork+exec 解析输出,既慢又脆弱。路径 /proc/cpuinfo 也非所有内核都启用(如某些容器或精简系统可能没 /proc)。
真正需要跨平台运行时检测时,优先走编译期分支 + 显式构建约束,而不是现场解析字符串。
-
uname()系统调用比读文件更轻量,但返回的machine字段仍需字符串匹配(如"x86_64"、"aarch64"),易出错 - POSIX 标准不保证
uname的machine值格式统一,macOS 返回"x86_64",但 Apple Silicon 返回"arm64",而旧脚本可能只认"amd64" - 绝大多数场景下,你真正依赖的是当前进程的 ABI,不是系统型号——所以回到第一种方式更干净
混淆 size_t 和指针大小是常见误判点
有人用 sizeof(size_t) == 8 来判断 64 位,这在多数现代平台成立,但不绝对。C++ 标准只要求 size_t 足够存最大对象尺寸,没强制等于指针宽度。极少数嵌入式平台(如带大内存映射的 32 位 DSP)可能让 size_t 为 8 字节,而指针仍是 4 字节。
所以除非你明确在做内存分配边界计算,否则别拿 size_t 当架构标识用。
-
sizeof(void*)是唯一被广泛实践验证的、与 ABI 绑定最紧的指标 - 模板特化或
#if分支里,应基于sizeof(void*)或标准宏(如__SIZEOF_POINTER__)做判断,而不是靠推导 - CI 构建时最好显式指定
-m32/-m64并断言static_assert(sizeof(void*) == 8, "64-bit build required"),避免误发布
sizeof(void*) 一行解决。非要深挖系统能力时,平台 API 才是唯一可信来源——而且得小心 Wow64、容器 namespace、chroot 等环境带来的偏差。


















