Say I have a macro:
#define SUBST(MAGIC, ...) __VA_ARGS__  /* this won't work*/

And I want to call it like:
SUBST(int, MAGIC a = 1);

// expected output:
int a = 1;

Is there some set of wild indirections and expansions that I can use to force the expansion of MAGIC within the second argument with a value which depends on the call to the macro?
This comes up when the other arguments come from another layer and the SUBST macro is repeated many times with different values of MAGIC.
For example:
#define WRAP(function, MAGIC, stuff, ...) \
  void function(__VA_ARGS__) { stuff };
#define SUPERWRAP(function, stuff, ...) \
    WRAP(function, uint8_t, stuff##_u8, __VA_ARGS__) \
    WRAP(function, uint16_t, stuff##_u16, __VA_ARGS__)

SUPERWRAP(example, EXAMPLE_IMPL, template_t<MAGIC>, int)

Which cannot be solved in templates because:
#define WRAP(function, stuff, ...) \
  template<class MAGIC>
  int function(__VA_ARGS__) { stuff }
WRAP(example, /*...*/, template_t<MAGIC>, int)

doesn't allow for specialised implementaion, and and taking the type as a templatea argument in the specialisation is a partial specialisation which is also illegal.

Is it possible to replace a word used within an argument to a preprocessor macro?

Is it possible to replace a word used within an argument to a preprocessor macro?

No, it is not possible to replace a word used within an argument to a preprocessor macro.

SUBST(int, MAGIC a = 1);
// expected output:
int a = 1;


That is not possible.

Is there some set of wild indirections and expansions that I can use to force the expansion of MAGIC within the second argument with a value which depends on the call to the macro?

No.

For example: #define WRAP(function, MAGIC, stuff, ...) \

Using C macros to generate function definition results in hard to read, maintain and debug code that no one is ever able to fix or do anything with later. Consider writing the stuff that you want line by line.
You could consider using a better preprocessor, like jinja2, m4 or php.
