首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于前一个值的X-宏枚举

基于前一个值的X-宏枚举
EN

Stack Overflow用户
提问于 2016-07-22 18:32:00
回答 2查看 387关注 0票数 3

我想生成一个带有X-Macro的枚举。枚举必须基于prev大小递增。

我有这个

代码语言:javascript
运行
复制
#define LIST
VAR(one, 0x02)
VAR(two, 0x02)
VAR(tree, 0x03)

并且想要生成这个

代码语言:javascript
运行
复制
enum{
one = 0x02 + 0,
two = 0x02 + one,
tree = 0x03 + two
}

但是这不起作用。

代码语言:javascript
运行
复制
#define VAR(NAME, SIZE) STORED_LOCATION_##NAME = SIZE + (STORED_LOCATION_##NAME-1)
enum{STORED_VARIABLES};
#undef VAR

这是可行的,但我认为它可以更容易。

代码语言:javascript
运行
复制
#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
EN

回答 2

Stack Overflow用户

发布于 2017-02-17 06:06:05

一个有效的半解决方案可能是声明一个等效的虚拟打包结构,然后使用它的字段的偏移量来获得所需的枚举值。

就像这样(在gcc手下工作):

My.def文件:

代码语言:javascript
运行
复制
VAR(one, 0x02)
VAR(two, 0x02)
VAR(tree, 0x03)

声明struct和enum:

代码语言:javascript
运行
复制
#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;
}

这给出了所需的:

1的

值是2

2的值是4

树的值为7

祝好运!

票数 0
EN

Stack Overflow用户

发布于 2017-04-26 00:45:59

您的问题令人困惑,因为您的第二个示例输出与您的第一个(期望的)输出不匹配。此外,您的第一个输出可能不是您真正想要的,因为生成的枚举实际上是随后的偏移量。更有可能的是,您可能希望生成枚举来作为命名字段的偏移量:

代码语言:javascript
运行
复制
enum
{
    one = 0,
    two = 2,
    tree = 4
};

下面的代码实际上是使用我通常用来创建偏移量的宏来生成的(请注意,它可以自由地与普通枚举一起使用):

代码语言:javascript
运行
复制
//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)
};

如果你真的想(这看起来很奇怪):

代码语言:javascript
运行
复制
enum
{
    one = 2,
    two = 4,
    tree = 7
};

您必须重新制定offset宏。

代码语言:javascript
运行
复制
#define ENUM_END_OFFSET(enumTag, size) _ignore1##enumTag, enumTag = _ignore1##enumTag + (size), _ignore2##enumTag = enumTag - 1,
enum 
{
    VAR_LIST(ENUM_END_OFFSET)
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38524206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档