7

I'm trying to pass the parameters to macro SETBIT with another predefined macro like this:

#define SETBIT(ADDRESS,BIT,N) {(N) ? (ADDRESS &= ~(1<<BIT)) : (ADDRESS |= (1<<BIT))}
#define DAC_SYNC PORTB,3,POS
SETBIT(DAC_SYNC);

However I receiver error:

macro SETBIT requires 3 parameters only 1 given

There is an article with the following recommendations:

to prevent misnesting of arithmetic operations: #define foo (a,b) or #define bar(x) lose((x))

But even though I still have an error. BTW, reading the article I've indicated I can make the following conclusion: preprocessor expands ALL macroses appearing. But actually it looks like macro #define DAC_SYNC PORTB,3,POS is not expanding by preprocessor.

Could anyone make more clear how the GCC's preprocessor works?

2 Answers 2

10

This works:

#define SETBIT2(ADDRESS,BIT,N) ((N) ? (ADDRESS &= ~(1<<BIT)) : (ADDRESS |= (1<<BIT)))
#define SETBIT(PARAMS) SETBIT2(PARAMS)
#define PORTB 5
#define POS 7
#define DAC_SYNC PORTB,3,POS

int main() {
  int a = SETBIT(DAC_SYNC);
  return 0;
}
Sign up to request clarification or add additional context in comments.

4 Comments

That's worked!!! But actually I didn't get the point: why this solved the problem? Is there any clear article on the topic?
I would suggest #define SETBIT(...) SETBIT2(__VA_ARGS__) -- this way you can call SETBIT with a macro that expands to 3 args or with the 3 args directly.
@RomanMatveev: It works by adding an extra indirection that causes the DAC_SYNC macro to be expanded before parsing the arguments to SETBIT2. C macro expansion works by first parsing the arguments, then expanding any macros in the arguments, then substituting the argments into the body, then rescanning the result for more macros to expand. The order is very important!
OMG! Now declaration SETBIT(PORTA,2,0) not working :(((((((
5

Just for the sake of completeness, that same manual you are linking to also states:

The number of arguments you give must match the number of parameters in the macro definition. When the macro is expanded, each use of a parameter in its body is replaced by the tokens of the corresponding argument.

So ooga's example is a nice demonstration of how macro expansion works recursively, first the outer macro gets expanded, then the argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.