1

I want to make a macro which doesn't use arguments but has predefined integer and string which is used.

I asked before about something similar with macro that has arguments and this is how it is:

#define BUZZER_PIN 1
#define BUZZER_PORT B
#define BUZZER_ALT 1

#define INIT_BUZZER_(PORTX, PIN, ALT)                                   \
    do {                                                                \
        PORT##PORTX##_PCR(PIN) = PORT_PCR_MUX(ALT) | PORT_PCR_DSE_MASK; \
        GPIO##PORTX##_PDDR |= (PIN)<<1;                                 \
       } while (0)

#define INIT_BUZZER(PORTX, PIN, ALT)                                    \
    INIT_BUZZER_(PORTX, PIN, ALT)

but what if I just want to have INIT_BUZZER that will be referenced to INIT_BUZZER_ and do all above?

I tried to:

#define INIT_BUZZER INIT_BUZZER_(BUZZER_PORT, BUZZER_PIN, BUZZER_ALT)

I am always having problem only with string and I don't understand that part well. If I call it this way I get BUZZER_PORT processed as string BUZZER_PORT not as the value of it = B

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • How about the stringify directive? `#BUZZER` will substiute to the value of the `BUZZER` macro surrounded by double quotes. –  Jul 11 '13 at 22:19
  • You cannot have two macros with the same name. – jxh Jul 11 '13 at 22:26
  • You aren't trying to define both versions of `INIT_BUZZER` at the same time, are you? – user2357112 Jul 11 '13 at 22:35
  • 1
    You can see its INIT_BUZZER and INIT_BUZZER_ so its different – user2566355 Jul 11 '13 at 22:37
  • The purpose of the original `INIT_BUZZER(...)` and `INIT_BUZZER_(...)` was to allow the arguments to `INIT_BUZZER` to be expanded before being passed to `INIT_BUZZER_`. You want instead a macro `INIT_BUZZER` that uses some canned parameters. Then, you should rename the old `INIT_BUZZER` to something else, and let your new `INIT_BUZZER` call that. I illustrate this in my answer. – jxh Jul 11 '13 at 22:40
  • See also [C preprocessor and concatenation](http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation/). – Jonathan Leffler Jul 11 '13 at 22:40

1 Answers1

2

You need another macro to expand the macro arguments before it is passed to INIT_BUZZER_.

#define INIT_BUZZER_X(PORTX, PIN, ALT)                                    \
    INIT_BUZZER_(PORTX, PIN, ALT)

#define INIT_BUZZER INIT_BUZZER_X(BUZZER_PORT, BUZZER_PIN, BUZZER_ALT)

Now, when you use INIT_BUZZER in your code, it will first expand into INIT_BUZZER_X with the three arguments. The preprocessor will then proceed to process INIT_BUZZER_X, in which it will expand each of the three arguments, and pass them to INIT_BUZZER_.

jxh
  • 69,070
  • 8
  • 110
  • 193