在if/else语句中使用#define宏定义如何避免重定义错误?
问题原因
宏属于预编译期语法,会在代码编译前就完成替换,完全不感知你写的运行时if/else分支逻辑,所有你写在分支里的#define语句都会被预编译器依次处理,同一个宏被多次定义就会触发重定义报错。
可行临时解决方案
你不需要修改原有引用BTNNUMBER_W、BTNNUMBER_H的业务代码,直接把最初定义的两个固定值宏替换成动态计算的宏即可:
// 直接替换掉原来的#define BTNNUMBER_W 60、#define BTNNUMBER_H 60 #define BTNNUMBER_W (IS_IPHONE_6_6S_6P_6SP_7_8 ? 30 : (IS_IPHONE_X ? 110 : 60)) #define BTNNUMBER_H BTNNUMBER_W
如果需要更清晰的逻辑,可以用GCC支持的语句表达式写法,可读性更高:
#define BTNNUMBER_W ({\ CGFloat width = 60;\ if (IS_IPHONE_6_6S_6P_6SP_7_8) width = 30;\ else if (IS_IPHONE_X) width = 110;\ width;\ }) #define BTNNUMBER_H BTNNUMBER_W
这个方案完全兼容你现有的所有代码,宏替换后会在运行时自动判断机型返回对应尺寸,不会出现重定义问题。
不推荐的写法说明
如果你一定要在分支中重定义宏,需要每次定义前先取消原有定义:
#undef BTNNUMBER_W #undef BTNNUMBER_H #define BTNNUMBER_W 30 #define BTNNUMBER_H 30
但该写法存在作用域坑:宏的作用域是从定义行到当前文件结束,和运行时分支无关,会导致后续所有代码都使用最后一次定义的宏值,大概率出现逻辑错误,非常不建议使用。
内容的提问来源于stack exchange,提问作者DannyRoy
相关产品推荐
相关产品推荐

