Stringify first level macro expansion C
Asked Answered
T

2

12

Is it possible to stringify this C macro:

 #define GPIO_INT_PIN (GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)

using something like

 MY_STRINGFY(GPIO_INT_PIN) 

to get

"(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)" ?

Toughminded answered 23/1, 2014 at 13:42 Comment(2)
What are you trying to accomplish?Chu
My purpose is to print a debug message about GPIO_INT_PIN that shows which GPIO is being initialized. GPIO_INT_PIN itself is defined on a .h file, and it can change from version to version.Toughminded
M
7

Yes it is possible. Read about stringizing in GCC cpp documentation.

 #define STRINGIFY(It) #It
 #define MY_STRINGIFY(It) STRINGIFY(It)

I corrected my answer thanks to Wojtek Surowka's one

then use MY_STRINGIFY(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5) which would work much better if you use an enum to define the constants, e.g.

enum Gpio_stuff_en {
     GPIO_PORT_D=5,
     GPIO_PIN_IRQ_RISING=17,
     GPIO_PIN5=23
};

Of course that won't work as you want if you need GPIO_PORT_D to be a macro, .e.g. because it expands to some non-constant-literal expression (like a variable, or an access to a field of some global structure, etc....)

As a counter-example:

#define FOO 1
#define BAR 2
#define STRINGIFY(s) #s
#define MY_STRINGIFY(s) STRINGIFY(s)

MY_STRINGIFY(FOO|BAR)

is expanded to "1|2" not to "FOO|BAR", if your remove the two #define-s for FOO and for BAR and replace them with

enum {
  FOO=1,
  BAR=2 };

you really get the expansion "FOO|BAR" as you want. Check with gcc -C -E ...

Also:

enum {FOO=1, BAR=2};
#define FOOORBAR (FOO|BAR)
#define STRINGIFY(s) #s
#define MY_STRINGIFY(s) STRINGIFY(s)

MY_STRINGIFY(FOOORBAR)

is expanded as "(FOO|BAR)" . But if you use #define for FOO and for BAR you get the "(1|2)" expansion.

Maybe you could add in your own header, after including the external header defining GPIO_PORT_D etc... as a literal constants, something like :

enum {en_GPIO_PORT_D= GPIO_PORT_D,
      en_GPIO_PIN_IRQ_RISING= GPIO_PIN_IRQ_RISING,
      en_GPIO_PIN5= GPIO_PIN5};
#undef GPIO_PORT_D
#undef GPIO_PIN_IRQ_RISING 
#undef GPIO_PIN5
#define GPIO_PORT_D en_GPIO_PORT_D
#define GPIO_PIN_IRQ_RISING en_GPIO_PIN_IRQ_RISING
#define GPIO_PIN5 en_GPIO_PIN5

and then you'll get more readable stringified constants (but not exactly what you dream of).

Mechelle answered 23/1, 2014 at 13:47 Comment(1)
I see. Thank you for your answer, but i don't think i can change the defines to enums because i'm not the maintainer of the file that defines them.Toughminded
P
2

If you have such two definitions

#define STRINGIFY(s) #s
#define MY_STRINGIFY(s) STRINGIFY(s)

MY_STRINGIFY does what you want - expands its argument and adds quotes after.

Pessimist answered 23/1, 2014 at 13:51 Comment(4)
But I think the OP might not want GPIO_PORT_D to be expanded.Mechelle
It is said clearly: I want MY_STRINGFY(GPIO_INT_PIN) to expand to "(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)" - sorry misread your concern (skipped the _D :))Pessimist
I don't think it is possible then - either you get GPIO_INT_PIN not expanded, or fully expandedPessimist
The problem is that GPIO_PORT_D, GPIO_PIN_IRQ_RISING and GPIO_PIN5 are macros too. I don't want them to be expanded, i only want to expand GPIO_INT_PIN.Toughminded

© 2022 - 2024 — McMap. All rights reserved.