原文:http://blog.csdn.net/dadoneo/article/details/8766972
工作中有个存储在flash中的结构体由于里面宏控制很复杂,所以其大小变化很大,而这个大小是受限的,常常稍不注意这个结构体大了会引起很严重的后果。网上查到一种方法在编译阶段检查结构体大小,利用的是数组大小限制和一些非法的运算编译错误提示实现。实现方法如下:
-
typedef struct
-
{
-
char a[100];
-
}T_XXX;
-
-
typedef struct
-
{
-
char a[99];
-
}T_QQQ;
-
-
-
-
/*检测结构体的大小是否等于特定值*/
-
#define SIZE_OF_TYPE_EQUAL_TO(type,size)\
-
static inline char size_of_##type##_equal_to_##size()\
-
{\
-
char __dummy1[sizeof(type)-size];\
-
char __dummy2[size-sizeof(type)];\
-
return __dummy1[-1]+__dummy2[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否不等于特定值*/
-
#define SIZE_OF_TYPE_UNEQUAL_TO(type,size)\
-
static inline char size_of_##type##_unequal_to_##size()\
-
{\
-
char __dummy1[0==(10/(sizeof(type)-size))];\
-
return __dummy1[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否不大于特定值*/
-
#define SIZE_OF_TYPE_NOT_LARGER_THAN(type,size)\
-
static inline char size_of_##type##_not_larger_than_##size()\
-
{\
-
char __dummy1[size-sizeof(type)];\
-
return __dummy1[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否不小于特定值*/
-
#define SIZE_OF_TYPE_NOT_SMALLER_THAN(type,size)\
-
static inline char size_of_##type##_not_smaller_than_##size()\
-
{\
-
char __dummy1[sizeof(type)-size];\
-
return __dummy1[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否小于特定值*/
-
#define SIZE_OF_TYPE_SMALLER_THAN(type,size)\
-
SIZE_OF_TYPE_NOT_LARGER_THAN(type,size)\
-
SIZE_OF_TYPE_UNEQUAL_TO(type,size)
-
-
-
-
/*检测结构体的大小是否大于特定值*/
-
#define SIZE_OF_TYPE_LARGER_THAN(type,size)\
-
SIZE_OF_TYPE_NOT_SMALLER_THAN(type,size)\
-
SIZE_OF_TYPE_UNEQUAL_TO(type,size)
-
-
-
-
/*检测结构体的大小是否小于特定值 版本2*/
-
#define SIZE_OF_TYPE_SMALLER_THAN2(type,size)\
-
static inline char size_of_##type##_smaller_than2_##size()\
-
{\
-
char __dummy1[size-sizeof(type)-1];\
-
return __dummy1[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否大于特定值 版本2*/
-
#define SIZE_OF_TYPE_LARGER_THAN2(type,size)\
-
static inline char size_of_##type##_larger_than2_##size()\
-
{\
-
char __dummy1[sizeof(type)-size-1];\
-
return __dummy1[-1];\
-
}
-
-
-
-
/*检测结构体的大小是否为特定值的整数倍*/
-
#define SIZE_OF_TYPE_IS_MULTIPLE_OF(type,size)\
-
static inline char size_of_##type##_is_multiple_of_##size()\
-
{\
-
char __dummy1[0-(sizeof(type)%size)];\
-
return __dummy1[-1];\
-
}
-
-
/***
-
好了,现在开始,想检查什么,调用相应的宏即可。
-
如果结构大小不符合要求,则会编译出错。
-
注意,对宏的调用,不要写在任何函数内:-)
-
***/
-
SIZE_OF_TYPE_EQUAL_TO(T_XXX,100)
-
SIZE_OF_TYPE_UNEQUAL_TO(T_XXX,99)
-
SIZE_OF_TYPE_NOT_LARGER_THAN(T_XXX,100)
-
SIZE_OF_TYPE_NOT_SMALLER_THAN(T_QQQ,98)
-
SIZE_OF_TYPE_LARGER_THAN(T_QQQ,96)
-
SIZE_OF_TYPE_SMALLER_THAN(T_QQQ,200)
-
-
SIZE_OF_TYPE_LARGER_THAN2(T_QQQ,96)
-
SIZE_OF_TYPE_SMALLER_THAN2(T_QQQ,200)
-
SIZE_OF_TYPE_IS_MULTIPLE_OF(T_QQQ,9)
-
-
-
-
intmain()
-
{
-
return 0;
-
}
SIZE_OF_TYPE_EQUAL_TO(type, size):
如果type != size,那么
__dummy1 ,__dummy2这2个数组在定义时肯定有一个是负数,数组在分配大小时会将大小视为无符号型处理,那么此时这个数组的大小将会变得很大,例如-1是0xFFFFFFFF(32位机上),数组存在的位置要么是堆栈 char a[5];要么是代码段chara[5] = {0}; 而堆栈,内存大小总有限制,所以预编译器会检查,并报错。
SIZE_OF_TYPE_UNEQUAL_TO(type, size):
如果2者相等,10/(sizeof(type)-size) 这个算数运算就会报错,0作除数了。
其他实现方法都采用了类似的原理。
阅读(4802) | 评论(0) | 转发(0) |