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?

Original source