我的#if #endif语句块是否有误?跨平台C++标准检测异常问题
跨平台检测C++标准的代码问题
我正在尝试检测编译器所使用的C++标准,Windows平台编译时代码可正常工作,但Linux平台编译时CPP_STANDARD始终为0,未被正确赋值。请问我的代码是否存在问题?
代码如下:
#define CPP_STANDARD 0L #ifdef _WIN32 // WIN32 START #if _MSVC_LANG == 202002L #define CPP_STANDARD 2020 #elif _MSVC_LANG == 201703L #define CPP_STANDARD 2017 #elif _MSVC_LANG == 201402L #define CPP_STANDARD 2014 #endif // WIN32 ENDIF #else // NOT WIN32 START #if __cplusplus == 202002L #define CPP_STANDARD 2020 #elif __cplusplus == 201703L #define CPP_STANDARD 2017 #elif __cplusplus == 201402L #define CPP_STANDARD 2014 #elif __cplusplus == 201103L #define CPP_STANDARD 2011 #endif #endif // NOT WIN32 ENDIF #if CPP_STANDARD == 0L #error "No CPP Standard detected" #endif
补充说明:我发现GCC将__cplusplus标志设置为201709,但我之前检测的是201703,是否应该改为检测>=201700?
问题分析与修复
核心问题
- GCC版本编号差异:GCC对C++17标准的
__cplusplus赋值为201709L(该标准的最终修订版编号),而非你代码中检测的201703L,严格相等判断导致匹配失败,CPP_STANDARD保留初始值0。 - 编译选项缺失:GCC默认未指定
-std参数时,会进入GNU扩展模式,__cplusplus会被定义为199711L(旧C++98标准值),即便编译器本身支持更高版本标准。
修复方案
- 改用范围判断:把严格相等
==替换为范围判断>=,兼容不同编译器对标准版本编号的细微差异,比如GCC的201709L会被正确识别为C++17。 - 指定编译参数:编译时必须添加对应标准的
-std选项,例如编译C++17代码用g++ -std=c++17 your_code.cpp,确保__cplusplus被正确赋值。
修改后的代码
#define CPP_STANDARD 0L #ifdef _WIN32 #if _MSVC_LANG >= 202002L #define CPP_STANDARD 2020 #elif _MSVC_LANG >= 201703L #define CPP_STANDARD 2017 #elif _MSVC_LANG >= 201402L #define CPP_STANDARD 2014 #endif #else #if __cplusplus >= 202002L #define CPP_STANDARD 2020 #elif __cplusplus >= 201703L #define CPP_STANDARD 2017 #elif __cplusplus >= 201402L #define CPP_STANDARD 2014 #elif __cplusplus >= 201103L #define CPP_STANDARD 2011 #endif #endif #if CPP_STANDARD == 0L #error "No CPP Standard detected" #endif
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

