背景
在微控制器代码中,我使用的是生产者提供的库,其中定义了许多常量.如果我的一些常量(与微控制器外部的组件共享,使用git-subtree)和微控制器常量之间存在不匹配,我试图给出错误.
例如,库定义:
#ifdef SOME_PARTICULAR_MODEL #define FLASH_BLOCK_SIZE ((uint8_t)64) /* else,other models */ #endif
在某处,在微控制器代码和PC上编译的一些代码之间共享的标题中,我有例如:
#define MYPROG_BLOCK_SIZE 64
为了确保这些常量匹配,在微控制器代码中,两个常量都存在,我有:
#if MYPROG_BLOCK_SIZE != FLASH_BLOCK_SIZE #error "mismatch between actual block size and defined block size" #endif
这是为了确保代码是否曾被移植到更大的微控制器,共享头也将被更新.
问题
问题是这会减少到:
#if 64 != ((uint8_t)64)
我不确定它是否是有效的C,但仍然使编译器窒息.测试时,我发现问题不在于uint8_t是一个typedef而且它仍然会被一个强制转换为int,例如.
问题
有没有办法从定义为((uint8_t)64)的值中删除(uint8_t)部分?如果没有,有没有办法改变它,所以表达式变成一个没有演员?
我想过将uint8_t定义为某些内容并在#if之后取消定义,但我无法弄清楚如何避免(Y)X的转换性质并将其转换为算术表达式.
解决方法
这是一个改进版本(第一个版本在下面).这个不依赖于演员是uint8_t;它将适用于任何格式的FLASH_BLOCK_SIZE替换列表((某种类型)).
#define MYPROG_BLOCK_SIZE 64 #define FLASH_BLOCK_SIZE ((uint8_t)64) #define B(x) #define C(x) B x #define D(x) C x #if MYPROG_BLOCK_SIZE != D(FLASH_BLOCK_SIZE) #error "mismatch between actual block size and defined block size" #endif
这是原始版本:
#define MYPROG_BLOCK_SIZE 64 #define FLASH_BLOCK_SIZE ((uint8_t)64) #define uint8_t #define Helper(x) x #define Deparenthesize(x) Helper x #if MYPROG_BLOCK_SIZE != Deparenthesize(Deparenthesize(FLASH_BLOCK_SIZE)) #error "mismatch between actual block size and defined block size" #endif #undef uint8_t
在编写代码时,我更喜欢静态断言,但上面做了你在预处理器中请求的.