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)" ?

2
  • 1
    What are you trying to accomplish? Commented Jan 23, 2014 at 13:55
  • 2
    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. Commented Jan 23, 2014 at 14:08

2 Answers 2

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).

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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.

4 Comments

But I think the OP might not want GPIO_PORT_D to be expanded.
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 :))
I don't think it is possible then - either you get GPIO_INT_PIN not expanded, or fully expanded
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.