【问题标题】:Macro that knows void * allocation type知道 void * 分配类型的宏
【发布时间】:2017-02-15 00:39:40
【问题描述】:

以这段代码为例:

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 似乎也不适用于宏。我该怎么做?

【问题讨论】:

  • 你是从什么投射出来的,是什么决定了你投射到什么?
  • 在我看来,尤其是从您尝试使用typeof 的方式来看,self->data 已经具有正确的类型并且不需要强制转换,或者您不知道正确的类型是什么并且您期望宏以某种方式提供您没有的信息。
  • @MateusFelipe:那是不可能的。名为“foo”的字段可以位于一个结构的开头和另一个结构的结尾。预处理器当然无法知道使用哪个。如果您有所有结构之间共有的字段,您可以创建一个包含它们的结构,并使该类型的字段成为所有“派生”结构的第一个字段。 (编辑:仍然不是一个好主意,因为它违反了严格的别名。)(编辑2:不,实际上很好,我没有直截了当。)
  • 您在编辑中寻找的内容无法完成。继续手动投射。
  • @MateusFelipe 您建议计算机应该根据您的分配方式知道如何投射它。我是说电脑不知道你是怎么分配的。

标签: c macros metaprogramming


【解决方案1】:

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

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 中是不可能的。

【讨论】:

    【解决方案2】:

    扩展我的评论:您必须将公共字段分组到另一个结构中,并使其成为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)
    

    【讨论】:

      猜你喜欢
      • 2016-12-24
      • 2019-03-27
      • 2017-09-21
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 2020-04-26
      相关资源
      最近更新 更多