知道void *分配类型的宏

时间:2017-02-15 00:39:41

标签: c macros metaprogramming

让我们以此代码为例:

typedef struct {
    int value;
    char another;
} foo;

typedef struct {
    float yet_another;
    long really_another;
} bar;

typedef struct {
    char* name;
    void* data;
} gen;

int main(int argc, char** argv) {
    gen foo_gen, bar_gen;

    foo_gen.name = "Foo";
    foo_gen.data = (foo*) malloc(sizeof(foo));

    bar_gen.name = "Bar";
    bar_gen.data = (bar*) malloc(sizeof(bar));

    ((foo*) foo_gen->data)->value = 0;
    ((bar*) bar_gen->data)->yet_another = 1.0f;

    return 0;
}

这段代码可以正常工作,所以我定义了2个宏来方便我的工作:

#define FOO_DATA(N, D) ((foo*) N->data)->D
#define BAR_DATA(N, D) ((bar*) N->data)->D

但似乎过于重复。我希望它更通用,让宏知道它应该转换为哪种类型。我尝试使用__auto_type

#define DATA(N, D) (__auto_type N->data)->D

但它没有用。似乎typeof也不适用于宏。我该怎么办?

2 个答案:

答案 0 :(得分:3)

如果我和其他评论者理解正确,您希望能够做到这样的事情:

struct a {
    int field1;
} a;

struct b {
    int field2;
} b;

void *self1 = &a;
void *self2 = &b;

int f1 = MAGIC(self1)->field1;
int f2 = MAGIC(self2)->field2;

MAGIC的某些定义。

这在C中是不可能的。

答案 1 :(得分:0)

扩展我的评论:您必须将公共字段分组到另一个结构中,并将其作为self->data中可能结构的第一个字段:

struct common {
    int foo;
};

struct a {
    struct common common;
    int bar;
};

struct b {
    struct common common;
    int baz;
};

#define $(D) (((struct common*) self->data)->D)