I am working on feature requests 22873 (multiple fake cursors) and 17684 (crosshairs that track the cursor position). window.h defines four different caches of fake cursors, with the only difference between them being their names: struct multiple_cursors_cache *temp_elts; ptrdiff_t temp_elts_allocated; int temp_nelts; struct multiple_cursors_cache *mc_elts; ptrdiff_t mc_elts_allocated; int mc_nelts; struct multiple_cursors_cache *ch_elts; ptrdiff_t ch_elts_allocated; int ch_nelts; struct multiple_cursors_cache *fc_elts; ptrdiff_t fc_elts_allocated; int fc_nelts; I am trying to create two functions (reset and populate) to manage all four caches, but am having troubling figuring out how to substitute the names of the applicable caches depending upon which cache is needed. I tried several variations of the following approach, but ran into problems either compiling or Emacs crashed when the crosshairs feature was activated. struct multiple_cursors_cache **foo_elts = w->ch_elts; ptrdiff_t *foo_elts_allocated = &w->ch_elts_allocated; int *foo_nelts = &w->ch_nelts; Q: What is the best way to create (1) a reset function and (2) a populate function that can handle all four caches? void mc_reset_cache (struct window *w, ...) { if (BUFFERP (w->contents) && NILP (BVAR (XBUFFER (w->contents), crosshairs)) && foo_nelts > 1) { /* Decrease the size of the array to a bare minimum. */ xnrealloc (foo_elts, 1, sizeof *foo_elts); foo_nelts = 0; foo_elts_allocated = 1; } else if (BUFFERP (w->contents) && !NILP (BVAR (XBUFFER (w->contents), crosshairs))) { /* Set all _used_ elements of the array to zero. elts_allocated remain the same. */ memset (foo_elts, 0, foo_nelts * (sizeof *foo_elts)); foo_nelts = 0; } } void mc_populate_cache (struct window *w, ...) { if (BUFFERP (w->contents) && !NILP (BVAR (XBUFFER (w->contents), crosshairs))) { /* Increase the size of the array. */ if (foo_elts_allocated < foo_nelts && foo_nelts < max_elts) { int old_alloc = foo_elts_allocated; int new_elts = foo_nelts - foo_elts_allocated; foo_elts = xpalloc (foo_elts, &foo_elts_allocated, new_elts, INT_MAX, sizeof *foo_elts); memset (foo_elts + old_alloc, 0, (foo_elts_allocated - old_alloc) * sizeof *foo_elts); } /* Below this comment is where the applicable cache will be populated. */ } } Attached is a draft patch that applies to the master branch as of 04/08/2019 (a038df77de7b1aa2d73a6478493b8838b59e4982).