MSVC枚举中报'DOUBLE'重定义,Unix平台无此问题
RetroBASIC移植Windows MSVC编译令牌重定义问题解决
问题背景
基于Lex/Yacc/C开发的RetroBASIC原在Mac平台开发,移植到Windows CLI环境时,已完成时间调用、命令行参数适配及空指针问题修复,仅剩一个编译错误:MSVC提示DOUBLE、INTEGER、INPUT令牌重定义。Bison生成的头文件中枚举定义如下:
enum yytokentype { STRING = 258, NUMBER = 259, DOUBLE = 260, SINGLE = 261, INTEGER = 262, };
该代码在Unix平台正常运行,冲突原因并非MSVC大小写不敏感,而是Windows系统头文件中存在同名宏定义(如部分SDK头文件会定义#define DOUBLE double),预处理阶段会替换代码中的令牌名称,导致枚举定义与系统宏冲突。
解决方案(无需修改令牌名称)
1. 给Bison令牌添加前缀(推荐)
在Yacc文件开头添加Bison的%define api.token.prefix选项,为所有生成的枚举令牌添加自定义前缀,避免与系统宏冲突:
%define api.token.prefix {RETRO_} %token <s> STRING %token <d> NUMBER DOUBLE SINGLE INTEGER
添加后,Bison生成的枚举会自动带前缀:
enum yytokentype { RETRO_STRING = 258, RETRO_NUMBER = 259, RETRO_DOUBLE = 260, RETRO_SINGLE = 261, RETRO_INTEGER = 262, };
同时Bison会自动生成令牌名的宏映射(如#define STRING RETRO_STRING),无需修改Lex或Yacc代码中的令牌引用,完全兼容原有代码。
2. 临时屏蔽系统宏(不推荐)
如果无法修改Bison配置,可在包含Bison生成的头文件前,手动取消冲突宏的定义:
// 屏蔽冲突的系统宏 #undef DOUBLE #undef INTEGER #undef INPUT // 包含解析器头文件 #include "retrobasic.tab.h"
此方法可能影响Windows系统API的正常使用,仅作为临时应急方案。
3. 调整头文件包含顺序
将Bison生成的头文件放在所有Windows系统头文件之前包含,确保枚举定义先于系统宏被编译器处理。但此方法可靠性较低,若后续系统头文件更新新增冲突宏,问题可能复现。
内容的提问来源于stack exchange,提问作者Maury Markowitz
相关产品推荐
相关产品推荐

