我正在为闪存驱动程序编写代码,有时我必须检查某些位置是否为空,即包含0xff。
有时我检查字节,有时候检查更长的值。所以我希望有一个定义来捕获一个无类型的1位字符串,我可以用来比较它。
它适用于8,16和32位宽的有符号和无符号变量。
我已尝试过以下两项:
#define ERASED (-1)
#define ERASED (~0)
如果我然后编译以下代码(所有无符号变量):
if (some32bitvar == ERASED)
{
....
}
if (some16bitvar == ERASED)
{
....
}
if (some8bitvar == ERASED)
{
....
}
编译器对16位和32位变量感到满意,但抱怨8位变量:
[Warning(ccom)] this comparison is always true
注意:体系结构和编译器是16位的,因此int是16位。
编译器是正确的,因为它将some8bitvar
扩展为int
,产生0x00nn
。然后,它会将其与ERASED
进行比较,后者也会扩展为int
,从而产生0xffff
。
一个简单的解决方案是使用:
if (~some8bitvar)
{
....
}
但是,它使用了一个已删除闪存的隐含知识,我想抽象出来并且它模糊了语句的作用。
另一种解决方案是使用:
if (some8bitvar == (typeof(some8bitvar)) ERASED)
{
....
}
但是这使得代码不太清晰,我的编译器也不支持typeof
宏。
如何定义ERASED
以使其与所有类型相比起作用?
答案 0 :(得分:1)
定义像
这样的宏 #define IsErased(val) ((~(val))==0)
并像
一样使用它 if (IsErased(someXXbitvar)) ...
这为您提供了所需的抽象,并使代码可读。
(如果你有一个现代的C11编译器,你可以尝试通过重载函数和_Generic
关键字来实现它,为每种类型提供不同的实现)。但我想上面的解决方案对你的情况来说已经足够了,它非常简单,也适用于较旧的编译器。