If the root name is always the same you could use:
#define SET_COMPOSITE(root) SET(root##_PORT, root##_MASK)
If the root name is always the same you could use:
#define SET_COMPOSITE(root) SET(root##_PORT, root##_MASK)
Substitution of parameters in the expansion of function-like macros happens in a set way. All arguments which don't appear after the #
operator or either side of a ##
are fully macro expanded when they are replaced, not before the function-like macro is expanded.
This means that to make a single macro become two macro arguments a round of macro substitution must occur before the required function like macro is itself expanded.
This means that the solution of a second function like macro that expands to the desired function-like macro is the simplest solution.
i.e. given your original SET
definition
#define SET(reg,bits) *((volatile unsigned long*)(& reg+SET_OFF)) = bits
and a macro that expands to two potential arguments
#define STATUS_LED_PORT LATB
#define STATUS_LED_MASK 0x0040;
#define STATUS_LED STATUS_LED_PORT, STATUS_LED_MASK
You have to use another function-like macro to get the substitution that you need.
e.g.
#define SET2(x) SET(x)
Then SET2( STATUS_LED )
expands as follows.
SET( LATB , 0x0040; )
then
*((volatile unsigned long*)(& LATB + 2 )) = 0x0040;
This isn't valid as there are not enough arguments to the SET
macro; the parameters are matched to arguments before any expansion of the argument occurs. My compiler generates an error; the behaviour isn't defined.
SET( STATUS_LED )