判断msvc编译器只认_msc_ver宏,它在msvc和clang-cl下均定义且值稳定(如vs2022为1930);区分clang与gcc需组合判断:__clang__且未定义_msc_ver为原生clang,__gnuc__且未定义__clang__为真正gcc;__cplusplus仅表标准版本,不可用于识别编译器厂商。

直接看 _MSC_VER、__clang__、__GNUC__ 这三个宏是否存在且有效,就能准确区分 MSVC、Clang、GCC —— 其他方式(比如查 __cplusplus 或 sizeof 行为)不可靠,也非标准做法。
怎么判断是不是 MSVC 编译器
只认 _MSC_VER:它在 MSVC 和 clang-cl 模式下都会被定义,且值稳定递增(VS2019=1920,VS2022=1930)。这是唯一可信赖的 MSVC 标识。
-
#if defined(_MSC_VER)✅ 安全;#ifdef _MSC_VER && _MSC_VER >= 1930❌ 预处理器不支持&&,语法错误 - 别用
__clang__反向排除:Clang 在 Windows 上启用-fms-compatibility时也会定义_MSC_VER,此时它就是“MSVC 兼容模式”,该按 MSVC 路径走 - 不要碰
_MSC_FULL_VER:构建号变化无规律,无法用于条件编译
怎么区分 Clang 和 GCC
Clang 默认会定义 __GNUC__(为了兼容),所以单靠它不能断定是 GCC。必须组合排除:
-
#if defined(__clang__) && !defined(_MSC_VER)→ 原生 Clang(非 clang-cl) -
#if defined(__GNUC__) && !defined(__clang__)→ 真正的 GCC(或 ICC/TCC 等 GNU 兼容编译器) - 如果只写
#ifdef __GNUC__,在 Clang 下也会进分支,可能触发 GCC 特有语法报错(比如__attribute__((optimize("O3"))))
为什么不能用 __cplusplus 判断编译器厂商
__cplusplus 只表示 C++ 标准版本(如 201703L),不是编译器身份标识。g++ 和 clang++ 都会定义它,GCC 的 C 编译器 gcc 不定义它 —— 但这和“是否是 GCC 编译器”无关,因为 g++ 才是 C++ 前端。
- 想判断“当前是不是 C++ 编译器”?看
__cplusplus是否定义 ✅ - 想判断“是不是 GCC 厂商的编译器”?必须靠
__GNUC__+ 排除__clang__✅ - 用
sizeof('a') == 1或空结构体大小来区分 gcc/g++?属于未定义行为依赖,不同版本可能变,绝对不要用
最易忽略的一点:clang-cl 下 _MSC_VER 和 __clang__ 同时存在,这不是冲突,而是设计使然——它意味着你正在使用 Clang,但目标 ABI、头文件、链接规则都对齐 MSVC。此时应优先响应 _MSC_VER,而非强行走 Clang 分支。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











