1.序
数组越界时常有发生,如果我们能够让编译器提醒我们犯错那是最好。
2.例子
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_CARDINALITY(Array) (sizeof(Array) / sizeof(*(Array)))
#undef YIN_VERIFY
#define YIN_VERIFY(name,cond) static char name ## dummy [sizeof(struct { unsigned char dummy:((cond)?1:-1);})] __attribute__ ((unused))
int yin_util_str2enum(const char *const*types,
unsigned int ntypes,
const char *type);
const char *yin_util_enum2str(const char *const*types,
unsigned int ntypes,
int type);
#define YIN_ENUM_IMPL(name, lastVal, ...) \
static const char *const name ## TypeList[] = { __VA_ARGS__ }; \
YIN_VERIFY(name,(ARRAY_CARDINALITY(name ## TypeList) == lastVal)); \
const char *name ## TypeToString(int type) { \
return yin_util_enum2str(name ## TypeList, \
ARRAY_CARDINALITY(name ## TypeList), \
type); \
} \
int name ## TypeFromString(const char *type) { \
return yin_util_str2enum(name ## TypeList, \
ARRAY_CARDINALITY(name ## TypeList), \
type); \
}
#define YIN_ENUM_DECL(name) \
const char *name ## TypeToString(int type); \
int name ## TypeFromString(const char*type);
/* Exported functions ------------------------------------------------------- */
int yin_util_str2enum(const char *const*types,
unsigned int ntypes,
const char *type)
{
size_t i;
if (!type)
return -1;
for (i = 0; i < ntypes; i++){
if (0 == strcmp(types[i], type))
return i;
}
return -1;
}
const char * yin_util_enum2str(const char *const*types,
unsigned int ntypes,
int type)
{
if (type < 0 || type >= ntypes)
return NULL;
return types[type];
}
//
enum {
EUNKOW,
ENAME,
EAGE,
EBUTT
};
YIN_ENUM_IMPL(student,EBUTT,"uknow","name")
int
main(int argc, char *argv[])
{
return 0;
}
执行报错:
enum2str.c:7:72: error: negative width in bit-field 'dummy'
#define YIN_VERIFY(name,cond) static char name ## dummy [sizeof(struct { unsigned char dummy:((cond)?1:-1);})] __attribute__ ((unused))
^
enum2str.c:20:2: note: in expansion of macro 'YIN_VERIFY'
YIN_VERIFY(name,(ARRAY_CARDINALITY(name ## TypeList) == lastVal)); \
^
enum2str.c:72:1: note: in expansion of macro 'YIN_ENUM_IMPL'
YIN_ENUM_IMPL(student,EBUTT,"uknow","name")
^
将 YIN_ENUM_IMPL(student,EBUTT,”uknow”,”name”) 改为 YIN_ENUM_IMPL(student,EBUTT,”uknow”,”name”,”age”) 错误解决。