C - emulate 'mutable' from C++
c, constants, mutable
Solution
You could(1) restructure your code and add a layer of indirection:
struct expensive; // Forward declaration, ignore
// One could also use a struct expensive * (a pointer) instead
// of this structure. IMO giving it a name is the better option.
struct expensive_handle {
struct expensive * target;
};
// Store the simple data members as usual, store a pointer to a
// handle (pointer) to the expensive ones
struct my_struct {
int simple;
struct expensive_handle * handle;
};
struct expensive {
int content; // whatever
};
Creating a `my_struct` must create the additional pointer/handle used for the indirection:
struct my_struct * new() {
struct my_struct * data = malloc(sizeof(*data));
// Error handling please
// Set simple data members
data->handle = malloc(sizeof(*(data->handle)));
// Error handling please
data->handle->target = NULL;
return data;
}
The `target` member (which will point to the expensive data once it is computed) is set to `NULL` initially.
Accessing (and thus possibly lazy computation of) the expensive data members is then possible even with a `const` qualified `my_struct`, because no data member of that `my_struct` is changed:
int get_expensive(struct my_struct const * ptr) {
if (ptr->handle->target == NULL) {
ptr->handle->target = malloc(sizeof(struct expensive));
// Error handling please
puts("A hell of a computation just happened!");
ptr->handle->target->content = 42; // WOO
}
return ptr->handle->target->content;
}
The only thing that changes is the data member of `*(ptr->handle)`, a `struct expensive_handle`. Which is not const qualified (only the pointer to it named `handle` is).
Test (Live on ideone):
int main(void) {
struct my_struct * p = new();
printf("%d\n", get_expensive(p));
printf("%d\n", get_expensive(p));
}
(1) Whether this is reasonable or a complete waste of resources (both programmer and computation) cannot be decided from your dummy example, though.
Problem
I have a C structure like this: ``` struct my_struct { int i; double d; struct expensive_type * t; }; ``` An instance of this structure is created and initialized as: ``` struct my_struct * my_new( int i , double d) { struct my_struct * s = malloc( sizeof * s); s->i = i; s->d = d; s->t = NULL; return s; } ``` Calculating the `struct expensive_type * t` member is quite expensive, and might not be needed - it is therefor just initialized to `NULL` - and later calculated on demand: ``` const struct expensive_type * my_get_expensive( const struct my_struct * s) { if (!s->t) s->t = my_expensive_alloc( s->i , s->d ); return s->t; } ``` In C++ I would have used `mutable` on the `struct expensive_type *`member, is it possible to achieve something similar in C, i.e. casting away the const locally: ``` { struct my_struct * mutable_s = (struct my_struct*) s; mutable_s->t = ...; ``` } Or is removing `const` in the signature my only standard-compliant alternative?