Text replacement before macro

Viewed 36

I have to edit the content of PORTXbits.RXY with X and Y that can vary (known at compilation but vary in the code). I would like to be able to write someting like PORTBIT(X, Y) = 1; with X defined unsing a define to only have to change it one time in the code.

I have written

#define X A
#define Z B
#define PORTBIT(X, Y) PORT ##Xbits.R ##X ##Y

PORTBIT(X, 0) = 1; // => PORTXbits.RX0 = 1; I want PORTAbits.RA0 = 1;
PORTBIT(Z, 0) = 1; // => PORTZbits.RZ0 = 1;

thats works BUT X is never replaced because the preprocessor replace as it go trough the code, so PORTBIT is replaced before.

Is there anyway to accomplish this replacement before ?

2 Answers

Xbits is token Xbits. You have to join X with bits if you want X to be replaced.

#define PORTBIT(X, Y)    PORT##X##bits.R##X##Y

The arguments are replaced, not expanded, when under operator ##. You have to do another pass to let them expand - for example to make Z expand to B.

#define PORTBIT_IN(X, Y)    PORT##X##bits.R##X##Y
#define PORTBIT(X, Y)       PORTBIT_IN(X, Y)

You need to catenate X also to whatever comes later, as in:

#define PORTBIT(X, Y) PORT ## X ## bits.R ## X ## Y
PORTBIT(A,0); /* -> PORTAbits.RA0 */

a good way to test it is to run it through the preprocessor

$ cpp <file.c | less
...
PORTAbits.RA0;
...
$ _

IMHO, to learn how the preprocessor works this exercise is fine... but don't try this in production code that scans your code searching for identifiers.

Related