c - Concatenation macro not properly expanding macro parameter -
the macro of interest (ioport_create_pin) part of library , works desired in general. converts specific pin on specific port library internal unique numeric representation.
it defined as:
#define ioport_create_pin(port, pin) ((ioport_ ## port) * 8 + (pin)) normal usage be
ioport_create_pin(portd, 4) for example, concatenate ioport_ , portd ioport_portd. ioport_portd in example internal definition of library further expands numeric value.
however, since portd (defined #define portd (*(port_t *) 0x0660), not relevant here) part of definition
#define flashport portd so using
ioport_create_pin(flashport, 4) wrongly concatenates ioport_flashport instead of desired ioport_portd inside ioport_create_pin definition.
i had @ this interesting answer , tried apply 1 level of indirection hoping macro expanded, wasn't able right.
is there way "wrap" macro somehow make compiler evaluate flashport portd before concatenation?
edit:
john pointed out problem wrapping is, flashport expanded recursively, not flashport portd, (*(port_t *) 0x0660).
is there workaround?
normally, arguments function-like macro macro-expanded before being substituted macro's replacement text. argument expansion suppressed, however, macro arguments operands of concatenation (##) or stringification (#) operator -- that's reason performing double-expansion if want concatenate or stringify macro's replacement value instead of name.
i can not change ioport_create_pin macro. there way "wrap" macro somehow make compiler evauate flashport portd before concatenation?
my understanding want define new macro, e.g. wrapper() can invoke instead of ioport_create_pin(), expansion same ioport_create_pin() arguments portd, 4, , expansion not change same when flashport used instead of portd first argument.
whether doable depends in part on macro arguments. generally, straight-up wrapper understand asking for:
// illustrative purposes: #define ioport_portd correct! #define ioport_flashport wrong! // specified in question: #define flashport portd #define ioport_create_pin(port, pin) ((ioport_ ## port) * 8 + (pin)) // wrapper: #define wrapper(port,pin) ioport_create_pin(port, pin) // demo: direct call: ioport_create_pin(flashport, 4) wrapped call: wrapper(flashport, 4) wrapped call: wrapper(portd, 4) the preprocessor exands to:
direct call: ((wrong!) * 8 + (4)) wrapped call: ((correct!) * 8 + (4)) wrapped call: ((correct!) * 8 + (4)) the catch here if portd defined macro in own right, hosed. cannot expand flashport portd; if flashport expanded result of expansion expanded again, recursively, before substituted.
alternative approach
as far know or can determine, not possible create general-purpose alias preprocessor macro. no token-pasting or stringification involved, can have done, , define 1 macro expand name of another, doesn't play pasting or stringification.
if for-purpose solution acceptable, however, there alternatives. example, if can identify token-pasting operations can involve alias, can provide aliases pasted-together macros, too. in case, might this:
// illustrative purposes: #define ioport_portd correct! #define portd oops // specified in question: #define flashport portd #define ioport_create_pin(port, pin) ((ioport_ ## port) * 8 + (pin)) // patch token-pasting: #define ioport_flashport ioport_portd // demo: direct call: ioport_create_pin(flashport, 4) the preprocessor expands to
direct call: ((correct!) * 8 + (4)) that doesn't scale well, of course, , requires knowledge or study of overall macro set involved, solve limited-scope problem presented in question.
Comments
Post a Comment