C 基于上一个值的X宏枚举
我想用X宏生成一个枚举。枚举必须根据上一个大小递增 我有这个C 基于上一个值的X宏枚举,c,enums,c-preprocessor,x-macros,C,Enums,C Preprocessor,X Macros,我想用X宏生成一个枚举。枚举必须根据上一个大小递增 我有这个 #define LIST VAR(one, 0x02) VAR(two, 0x02) VAR(tree, 0x03) 并且想要生成这个 enum{ one = 0x02 + 0, two = 0x02 + one, tree = 0x03 + two } 但这是行不通的 #define VAR(NAME, SIZE) STORED_LOCATION_##NAME = SIZE + (STORED_LOCATION_##NAME-1
#define LIST
VAR(one, 0x02)
VAR(two, 0x02)
VAR(tree, 0x03)
并且想要生成这个
enum{
one = 0x02 + 0,
two = 0x02 + one,
tree = 0x03 + two
}
但这是行不通的
#define VAR(NAME, SIZE) STORED_LOCATION_##NAME = SIZE + (STORED_LOCATION_##NAME-1)
enum{STORED_VARIABLES};
#undef VAR
这是可行的,但我觉得可以更容易些
#define LIST \
VAR(one ) STR(STORED_LOCATION )\
VAR(two ) PRE(one )\
VAR(tree ) PRE(two )\
VAR(fore ) PRE(tree )\
enum
{
one = 0x00,
two = 0x01 + one,
tree = 0x01 + two,
fore = 0x01 + tree,
};
#define STR(OFFSET) OFFSET,
#define PRE(NAME) sizeof(##NAME) + STORED_LOCATION_##NAME,
#define VAR(NAME) STORED_LOCATION_##NAME =
enum{STORED_VARIABLES};
#undef VAR
#undef PRE
#undef STR
一个有效的半解决方案可能是声明一个等效的伪压缩结构,然后使用其字段的偏移量来获得所需的枚举值 这样(在gcc下工作): 文件“my.def”: 声明结构和枚举:
#define VAR(NAME, SIZE) char NAME[SIZE];
typedef struct __attribute__ ((__packed__)) {
#include "my.def"
} myEnumStruct;
#undef VAR
#define VAR(NAME, SIZE) NAME = (offsetof(myEnumStruct, NAME) + sizeof(((myEnumStruct*)0)->NAME)),
typedef enum{
#include "my.def"
} myEnum;
#undef VAR
int main(int argc, char **argv) {
myEnum t;
#define VAR(NAME, SIZE) t=NAME; printf("Value of " #NAME " is %i\n", t);
#include "my.def"
#undef VAR
return EXIT_SUCCESS;
}
这将提供所需的:
一的值为2二的值为4
树的值是7
祝你好运 您的问题令人困惑,因为第二个示例输出与第一个(期望的)输出不匹配。此外,您的第一个输出可能不是您真正想要的,因为生成的枚举实际上是后面的偏移量。更可能的情况是,您希望生成用作命名字段偏移量的枚举:
enum
{
one = 0,
two = 2,
tree = 4
};
下面的代码本质上是使用我通常用于创建偏移量的宏生成的(请注意,它可以自由地散布在普通枚举中):
如果你真的想要(这似乎很奇怪):
必须重新格式化偏移量宏
#define ENUM_END_OFFSET(enumTag, size) _ignore1##enumTag, enumTag = _ignore1##enumTag + (size), _ignore2##enumTag = enumTag - 1,
enum
{
VAR_LIST(ENUM_END_OFFSET)
};
//This macro makes it easy to define an enumeration that defines an offset, rather than
// an increment. The enumTag represents the offset and the size forces the following
// enumeration tag to be offset by that amount, rather than 1.
// _ignore##enumTag creates a throwaway enumeration that only exists to perform the offset.
#define ENUM_OFFSET(enumTag, size) enumTag, _ignore##enumTag = enumTag + (size) - 1
//VAR_(enumTag, size)
#define VAR_LIST(VAR_)
VAR_(one ,0x02)
VAR_(two ,0x02)
VAR_(tree ,0x03)
enum
{
VAR_LIST(ENUM_OFFSET)
};
enum
{
one = 2,
two = 4,
tree = 7
};
#define ENUM_END_OFFSET(enumTag, size) _ignore1##enumTag, enumTag = _ignore1##enumTag + (size), _ignore2##enumTag = enumTag - 1,
enum
{
VAR_LIST(ENUM_END_OFFSET)
};