【问题标题】:Stringify first level macro expansion CStringify 一级宏展开 C
【发布时间】:2014-02-14 02:26:56
【问题描述】:

是否可以对这个 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)"?

【问题讨论】:

  • 你想完成什么?
  • 我的目的是打印关于 GPIO_INT_PIN 的调试消息,显示正在初始化的 GPIO。 GPIO_INT_PIN 本身是在 .h 文件中定义的,它可以在不同版本之间更改。

标签: c macros c-preprocessor stringification


【解决方案1】:

是的,这是可能的。阅读 GCC cpp 文档中的 stringizing。

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

感谢Wojtek Surowka's one

,我更正了我的答案

然后使用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)

扩展为"1|2" 而不是"FOO|BAR",如果您删除FOO 和BAR 的两个#define-s 并将它们替换为

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)" 。但是,如果您将#define 用于FOO 和BAR,您将得到"(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

然后您将获得更具可读性的字符串化常量(但不完全是您梦寐以求的)。

【讨论】:

  • 我明白了。感谢您的回答,但我认为我不能将定义更改为枚举,因为我不是定义它们的文件的维护者。
【解决方案2】:

如果你有这样两个定义

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

MY_STRINGIFY 做你想做的事 - 扩展它的参数并在后面添加引号。

【讨论】:

  • 但我认为 OP 可能不希望 GPIO_PORT_D 被扩展。
  • 说得很清楚:我希望 MY_STRINGFY(GPIO_INT_PIN) 扩展为“(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)” - 抱歉误读了您的问题(跳过了_D :))
  • 我认为这是不可能的——要么你得到 GPIO_INT_PIN 没有扩展,要么完全扩展
  • 问题在于 GPIO_PORT_D、GPIO_PIN_IRQ_RISING 和 GPIO_PIN5 也是宏。我不希望它们被扩展,我只想扩展 GPIO_INT_PIN。
猜你喜欢
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多