【问题标题】:Is it possible to create an "anonymous" initializer in C99?是否可以在 C99 中创建“匿名”初始化程序?
【发布时间】:2012-12-15 20:26:37
【问题描述】:

我正在使用嵌套结构在普通 C 中创建一种“结构继承”。例如,我有一些这样的结构:

struct a {
    obj_type type_id;
    int x;
    int y;
}

struct b {
    struct a super;
    char* str;
}

struct c {
    struct a super;
    int* data;
    bool flag;
}

然后我创建一个枚举,如下所示:

typedef enum {
    OBJ_TYPE_A,
    OBJ_TYPE_B,
    OBJ_TYPE_C
} obj_type;

这让我可以通过检查它们的type_id 来确定各种对象的结构,然后转换为相应的结构来模拟继承。我的问题是我希望能够在不手动定义父结构的xy 属性的情况下初始化这些“子”结构。

基本上,我可以这样初始化一个指针:

struct b obj_b = { OBJ_TYPE_B, 0, 0, "foo" };
struct b *ptr_b = malloc(sizeof(struct b));
memcpy(ptr_b, &obj_b, sizeof(struct b));

但是,我宁愿有一个函数来为我做a 的初始化,所以我可以这样做:

struct b *ptr_b = object_create(OBJ_TYPE_B, { "foo" }, sizeof(struct b));

我已经创建了类似这样的函数的实现:

const struct a DEFAULT_A = { OBJ_TYPE_A, 0, 0 };

struct a object_create(obj_type type, void* data_ptr, size_t size) {
    struct a new_obj = malloc(size);
    memcpy(new_obj, &DEFAULT_A, sizeof(struct a));
    memcpy(new_obj + sizeof(struct a), data_ptr, size - sizeof(struct a));
    return new_obj;
}

但是,我不能真正使用它,因为我无法做这样的事情:

struct b *ptr_b = object_create(OBJ_TYPE_B, &{ "foo" }, sizeof(struct b));

有没有办法创建一种“匿名”数据块来传递给函数?还是我必须求助于宏之类的东西来完成这项工作?

【问题讨论】:

  • 不,但我认为您可能正在寻找 C++11 初始化程序列表。
  • @Mehrdad,这是一个 C 问题而不是 C++。
  • 除了 H2CO3 在他的回答中向您展示的复合文字外,您还可以查看 designated initializers,例如 { .toto = 42 }。你也可以根据structs 的嵌套结构更好地构造你的初始化器。

标签: c initialization c99


【解决方案1】:

C99 中确实可以实现您想要的。例如,上面的工作,你只需要抛弃结构文字:

#include <stdio.h>

struct s {
    char *a;
};

void f(struct s *p)
{
    printf("%s\n", p->a);
}


int main()
{
    f(&(struct s){ "hello world" });
    return 0;
}

this article 中有关该主题的更多信息:

复合文字产生左值。这意味着您可以获取复合文字的地址,即复合文字声明的未命名对象的地址。只要复合文字没有 const 限定类型,就可以使用指针对其进行修改。

【讨论】:

  • 所以,为了确认,我必须创建一个辅助结构,它只包含我的“子”结构独有的属性,然后转换成那个?
  • @JakeKing 是的,类似的。
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 2010-10-13
  • 1970-01-01
  • 2021-01-02
  • 2014-02-23
  • 1970-01-01
  • 2010-12-08
相关资源
最近更新 更多