STM32 Keil项目中GSL-Lite引入<array>编译报错求助
解决Keil老旧编译器下GSL-Lite引入std::array的编译错误
我来帮你搞定这个问题,直接从解决方案和底层原理两部分拆解:
一、快速修复:强制禁用array特性
最直接的办法是在引入GSL-Lite头文件前,手动把gsl_HAVE_ARRAY宏定义为0,让预处理器跳过<array>的引入:
// 在包含gsl-lite.hpp之前添加这行 #define gsl_HAVE_ARRAY 0 #include "gsl/gsl-lite.hpp"
如果你不想修改代码,也可以在Keil项目设置里添加全局宏:
- 打开
Project -> Options for Target -> C/C++ - 在
Preprocessor的Define栏里添加gsl_HAVE_ARRAY=0
二、拆解GSL-Lite的宏检测逻辑
先搞懂你疑惑的宏机制:gsl_HAVE(feature)是一个宏拼接工具,代码定义为:
#define gsl_HAVE( feature ) ( gsl_HAVE_##feature )
比如gsl_HAVE(ARRAY)会被预处理器展开成gsl_HAVE_ARRAY,本质就是把传入的feature名称和gsl_HAVE_拼接成一个新的宏。
GSL-Lite的特性判断逻辑是:
- 通过
gsl_CPLUSPLUS(对应编译器的__cplusplus宏)识别C++版本 - 当
gsl_CPP11_OR_GREATER(即gsl_CPLUSPLUS >= 201103L)为真时,才会自动定义gsl_HAVE_ARRAY=1 - 如果是C++98/03环境,理论上
gsl_HAVE_ARRAY不会被定义,#if gsl_HAVE(ARRAY)会判定为假,跳过<array>引入
你遇到的矛盾(编辑器灰显代码但编译报错),大概率是Keil编辑器的宏感知和实际编译器的预定义宏不一致——编辑器认为gsl_HAVE(ARRAY)为假,但编译时编译器的宏状态意外触发了<array>的引入。
三、验证编译器的__cplusplus实际值
要确认问题根源,可以先查看Keil编译器实际的__cplusplus值:
在代码里加一行预编译指令,编译时会在Build Output里打印对应值:
#pragma message "__cplusplus value is " #__cplusplus
如果输出的是C98的199711L,那GSL-Lite本不该触发gsl_HAVE_ARRAY,这时候手动定义gsl_HAVE_ARRAY=0就能彻底解决问题;如果是C11的201103L,说明编译器宣称支持C++11但未实现<array>,同样手动禁用这个特性即可。
内容的提问来源于stack exchange,提问作者Trick
相关产品推荐
相关产品推荐

