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

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -