To expand on the correct answer by @Moses, when the ## operator is present in a so-called "macro replacement list", there's two scenarios given some a ## b:
- Either a and b are function-like macro parameters, in which case they are expanded before token concatenation.
- Or a and b is something else, in which case the pre-processor applies the
## operator to the sequences of pre-processing tokens 'a' and 'b' respectively, not considering if those form valid pp-tokens that may be expanded.
For this reason, you can use the code somewhat as-is. However, MY_TIMER becomes problematic because once the preprocessor starts expanding macros, it goes all the way and expands TC0 too. We can solve that with a work around, moving the _ from the _Handler etc into the MY_TIMER macro:
#define MY_TIMER TC0 ## _
And then we need some helper macros to expand MY_TIMER before token concatenation, we can't do MY_TIMER ## _Handler or we'd just end up with MY_TIMER_Handler with no connection to TC0:
#define CONCAT(a,b) a ## b
#define EXPAND_CONCAT(a,b) CONCAT(a,b)
#define MY_TIMER TC0 ## _
#define MY_TIMER_HANDLER EXPAND_CONCAT(MY_TIMER, Handler)
Full example:
#include <stdio.h>
typedef struct
{
int tc0_stuff [123];
} Tc;
#define TC0 ((Tc *)0x42003000UL)
#define CONCAT(a,b) a ## b
#define EXPAND_CONCAT(a,b) CONCAT(a,b)
#define MY_TIMER TC0 ## _
#define MY_TIMER_HANDLER EXPAND_CONCAT(MY_TIMER, Handler)
void TC0_Handler (void)
{
printf("handling mysterious stuff");
TC0->tc0_stuff[0] = 456;
}
int main (void)
{
MY_TIMER_HANDLER();
}
#undef TC0) before you use it.##is always applied before any macro expansion inside that macro.