我有以下类型,例如:
struct outer {
struct inner {
const int c;
int x;
} i;
int y;
};
我想要malloc outer
然后再初始化inner
以获得outer.i.c
的正确const行为。
例如,像
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'
的错误,因为它是一个赋值,而不是一个初始化。
有没有办法在编译器前面做这样的事情?让我们考虑使用*((int *) &o->i.c)
或使用memcpy在&o.i
上使用memcpy来躲避编译器。我可以得到他们需要的位置,但我正在寻找最不实际的方法来做到这一点。
我没有使用C ++(我正在使用C99)。
答案 0 :(得分: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;
}
请注意,这是一个比学术上更实用的解决方案,因此有些人可能会想要给我一些烂鸡蛋。
答案 1 :(得分: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;
我不完全确定它绝对是便携式的。