#define
#undef
#define大家应该很常用,或许#undef也用过吧。今天要讲的是在项目中遇到的些小问题。
以前的代码是为某一种板子写的,现在有了新的板子。所以既要支持新板子,又要保持向老的板子兼容。
但是两种板子的资源不同啊,举个简单的例子。两个板子上都有一个I2C MUX (pca9545)
但是,两个I2C 地址却不同。
老板子上这样定义
#define CFG_I2C_DEV_ADDR 0x70
新板子用的是0x68这个地址。
要怎么样才能使一套代码支持两个板子呢,前提是代码只编译一次。即编译生成的只有一个版本。
那么怎么确定板子类型?答案是只有运行时确定。
运行时确定板子类型所用的方法很简单,程序启动的时候读取板子EEPROM,根据EEPROM内容来决定是哪一种板子。
现在,要在运行后改变宏CFG_I2C_DEV_ADDR(其实运行后是不可能改变的,仍然是在预编译阶段就已经改变了)
作如下改动
if (MASTER_BOARD_TEMBO == master_board_type) { #ifdef CFG_I2C_DEV_ADDR #undef CFG_I2C_DEV_ADDR #endif #define CFG_I2C_DEV_ADDR 0x68 }这样改动之后,CFG_I2C_DEV_ADDR 必然被改成了0x68。
但一定要注意,这里虽然把它们写到了if语句里,其实,跟if语句一点关系都没有。
不管当前的板子是何种类型,都被改成了0x68.
因为这个东西是在预编译阶段就决定了的,跟运行时的状态无关!
这样一来,这种写法就不行了。因为这种改动是必然的!影响到了以前的板子类型。
所以,想在运行时去改变一个宏定义是不现实的。
其实没有更好的手段去解决这个问题,一般只能重新定义一个宏来描述这个地址,
于此,在代码中用到CFG_I2C_DEV_ADDR 的地方,就要分情况考虑了,如果是新板子,那么就用新的宏来替换
原来的CFG_I2C_DEV_ADDR。
结论:对于编译阶段和运行阶段一定要分清。