I have the following types, for illustration:
struct outer {
struct inner {
const int c;
int x;
} i;
int y;
};
I want to malloc outer
and then, later, initialize inner
to get the right const behavior for outer.ic
.
For example, something like
struct outer *o = malloc(sizeof *o);
o->y = find_y();
int cc = find_c();
int xx = find_x();
o->i = { .c = cc, .x = xx };
but this gives me an error about assignment of read-only member 'i'
, because it's an assignment, not an initialization.
Is there a way to do something like this that's up-front to the compiler? Let's consider tricks like casting away const with *((int *) &o->ic)
or using memcpy on &o.i
as sneaking around the compiler. I can get the bits where they need to be, but I am looking for the least sneaky way to do this.
I am not using C++ (I'm using C99).
The only really constant things are things residing in read-only memory. Malloc/calloc will never give you read-only memory. So that "const" there is a lie. Well, it is a hint for compiler(s) and to developer(s). I am not sure if there are any syntax sugars in C99 to address something that might seem an issue to someone, but here is how I would do it:
#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;
}
Please take into account that this is a more practical solution than academic, thus some people might want to throw a few rotten eggs at me for it.
I would probably do this:
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;
I am not completely sure that it is absolutely portable though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.