字符串化一级宏扩展C [英] Stringify first level macro expansion C
问题描述
是否可以对此C宏进行字符串化处理?
#define GPIO_INT_PIN (GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)
使用类似
MY_STRINGFY(GPIO_INT_PIN)
获得
"(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)"
?
是可以的.在GCC cpp
文档中了解字符串化.
#define STRINGIFY(It) #It
#define MY_STRINGIFY(It) STRINGIFY(It)
我更正了我的回答,这要感谢 Wojtek Surowka的
然后使用MY_STRINGIFY(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)
,如果您使用enum
定义常量,则效果会更好,例如
enum Gpio_stuff_en {
GPIO_PORT_D=5,
GPIO_PIN_IRQ_RISING=17,
GPIO_PIN5=23
};
当然,如果您需要GPIO_PORT_D
作为宏(例如.因为它扩展为某些非常数文字表达(例如变量或对某些全局结构的字段的访问等).
作为反例:
#define FOO 1
#define BAR 2
#define STRINGIFY(s) #s
#define MY_STRINGIFY(s) STRINGIFY(s)
MY_STRINGIFY(FOO|BAR)
如果您删除了FOO
和BAR
的两个#define
-s并替换为
扩展为"1|2"
而不是"FOO|BAR"
enum {
FOO=1,
BAR=2 };
您确实可以根据需要获得扩展"FOO|BAR"
.检查gcc -C -E
...
也:
enum {FOO=1, BAR=2};
#define FOOORBAR (FOO|BAR)
#define STRINGIFY(s) #s
#define MY_STRINGIFY(s) STRINGIFY(s)
MY_STRINGIFY(FOOORBAR)
扩展为"(FOO|BAR)"
.但是,如果对FOO
和BAR
使用#define
,则会得到"(1|2)"
扩展名.
也许您可以添加自己的标头,包括将GPIO_PORT_D
等定义为文字常量的外部标头,例如:
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
然后您将获得更具可读性的字符串化常量(但不完全是您梦dream以求的东西).
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)"
?
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).
这篇关于字符串化一级宏扩展C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!