字符串化一级宏扩展C [英] Stringify first level macro expansion C

查看:117
本文介绍了字符串化一级宏扩展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)

如果您删除了FOOBAR的两个#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)".但是,如果对FOOBAR使用#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆