编译期应优先使用预定义宏区分架构:__x86_64__或_m_x64表示x86-64,__aarch64__或_m_arm64表示arm64,__i386__或_m_ix86表示x86-32,运行时检测仅用于诊断等辅助场景。

编译期判断:用预定义宏区分 x86 和 ARM
绝大多数情况下,你不需要“运行时检测”,因为 C++ 程序在编译时就已绑定目标架构。直接查 __x86_64__、__i386__、__aarch64__、__arm__ 这类宏更可靠、零开销。
-
__x86_64__:64 位 x86(Linux/macOS/Windows MSVC/Clang/GCC 都支持) -
__i386__:32 位 x86(注意:GCC/Clang 有,MSVC 不定义此宏,它用_M_IX86) -
__aarch64__:ARM64(Linux/macOS/Clang/GCC;MSVC 用_M_ARM64) -
__arm__:32 位 ARM(较老,现代 ARM64 编译器通常不定义它) - MSVC 额外有:
_M_X64、_M_IX86、_M_ARM64—— 必须优先检查这些,因为 MSVC 不认 GCC 风格宏
示例写法:
#if defined(_M_X64) || defined(__x86_64__)
// x86-64
#elif defined(_M_IX86) || defined(__i386__)
// x86-32
#elif defined(_M_ARM64) || defined(__aarch64__)
// ARM64
#else
#error "Unsupported architecture"
#endif
运行时检测 Windows:用 GetNativeSystemInfo 或 IsWow64Process
仅当程序是通用二进制(如 x86_64 上跑的 WoW64 进程)或需适配运行时切换(如 .NET Core host),才需要运行时判断。Windows 下最稳妥的是 GetNativeSystemInfo,它返回的是系统原生架构,不受当前进程位数干扰。
- 调用前包含
<windows.h></windows.h> -
SYSTEM_INFO::dwProcessorType已废弃,应看wProcessorArchitecture字段 - 值为
PROCESSOR_ARCHITECTURE_AMD64、PROCESSOR_ARCHITECTURE_ARM64、PROCESSOR_ARCHITECTURE_INTEL等常量 - 别依赖
IsWow64Process单独判断——它只告诉你是不是在 WoW64 下运行,不能直接推出系统架构
简例:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
switch (si.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64: /* x86-64 */ break;
case PROCESSOR_ARCHITECTURE_ARM64: /* ARM64 */ break;
case PROCESSOR_ARCHITECTURE_INTEL: /* x86-32 */ break;
}
运行时检测 Linux/macOS:读取 /proc/cpuinfo 或 uname -m
Linux 下没有稳定 API,/proc/cpuinfo 是事实标准;macOS 没有 /proc,必须用 uname -m(对应 uname() 系统调用)。
- Linux:
grep -m1 'model name' /proc/cpuinfo不可靠(虚拟机/容器可能伪造),应看grep -m1 '^CPU architecture' /proc/cpuinfo(ARM)或grep -m1 '^flags.* lm ' /proc/cpuinfo(x86-64 的lmflag) - 更简单统一的做法:用
uname -m输出解析 ——x86_64、aarch64、armv7l等,POSIX 兼容 - C++ 中调用
uname()比popen("uname -m")更轻量且无 shell 依赖 - 注意:
uname -m返回的是当前进程视图(例如在 arm64 主机上跑 x86-64 容器,仍返回x86_64),不是宿主物理架构
跨平台封装建议:避免混合编译期+运行时逻辑
最容易出错的地方是把两者混用:比如在编译期已知是 __aarch64__,却还去调用 uname(),既冗余又可能因容器环境返回误导结果。
- 优先用编译期宏 —— 它决定代码生成路径、内联汇编、SIMD 指令选择,这才是真正影响行为的依据
- 运行时检测只用于日志、诊断、动态插件加载等辅助场景
- 若真要封装成函数,返回类型别用字符串,用 enum:
enum class Arch { X86_64, ARM64, X86, ARM32 };,避免 strcmp 和大小写问题 - 不要试图用
sizeof(void*) == 8判断 —— x86-64 和 ARM64 都满足,但无法区分二者
真正的难点不在“怎么查”,而在于想清楚:你要适配的是构建目标,还是部署环境?后者在容器和交叉编译中极易误判。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










