4

我有以下类型,用于说明:

struct outer {
  struct inner {
    const int c;
    int x;
  } i;
  int y;
};

我想 malloc outer,然后再初始化inner以获得正确的 const 行为outer.i.c

例如,像

struct outer *o = malloc(sizeof *o);
o->y = find_y();
int cc = find_c();
int xx = find_x();
o->i = { .c = cc, .x = xx };

但这给了我一个关于 的错误assignment of read-only member 'i',因为它是一个赋值,而不是一个初始化。

有没有办法在编译器前面做这样的事情?让我们考虑像在编译器周围偷偷摸摸地抛弃 const*((int *) &o->i.c)或使用 memcpy on之类的技巧。&o.i我可以在需要的地方找到它们,但我正在寻找最不偷偷摸摸的方法来做到这一点。

我没有使用 C++(我使用的是 C99)。

4

2 回答 2

1

唯一真正不变的东西是驻留在只读存储器中的东西。Malloc/calloc 永远不会给你只读内存。所以说“const”是个谎言。好吧,这是对编译器和开发人员的提示。我不确定 C99 中是否有任何语法糖来解决对某人来说可能存在问题的问题,但我会这样做:

#include <stdio.h>
#include <stdlib.h>

struct outer {
    struct inner {
        const int c;
        int x;
    } i;
    int y;
};

int main(void)
{
    struct outer    *o;

    o      = calloc(1, sizeof(struct outer));

    printf("before: %d %d %d\n", o->i.c, o->i.x, o->y);

    *((int *)&o->i.c) = 1;
    o->i.x = 2;
    o->y = 3;

    printf("after: %d %d %d\n", o->i.c, o->i.x, o->y);

    return 0;
}

请考虑到这是一个比学术更实用的解决方案,因此有些人可能想为此向我扔几个臭鸡蛋。

于 2012-05-17T14:19:29.777 回答
0

我可能会这样做:

struct outer_init {
  struct inner_init {
    int c;
    int x;
  } i;
  int y;
};

struct outer_init *oi = malloc(sizeof *oi);
oi->y = find_y();
oi->i.c = find_c();
oi->i.x = find_x();

struct outer *o = (struct outer *)oi;

我不完全确定它是绝对便携的。

于 2013-02-11T18:21:47.627 回答