【问题标题】:How to concatenate strings in the arguments of _Pragma如何在 _Pragma 的参数中连接字符串
【发布时间】:2017-08-18 17:50:43
【问题描述】:

_Pragma 的参数是一个字符串,所以我认为当您以正常的 c 预处理器方式将字符串粘贴在一起时(即将它们彼此相邻),您可以为 _Pragma 的参数形成一个新字符串。不过

_Pragma("GCC Poison " "puts")

因错误而失败

error: _Pragma takes a parenthesized string literal

如何避免这种情况?

这个特殊的例子不是很有用,并且有一个简单的解决方案,可以将它们全部从一个字符串开始,但最终目标是将宏字符串化到其中

【问题讨论】:

  • 一个DO_PRAGMA 宏作为here ?
  • 你试过_Pragma("GCC Poison ""puts")吗?
  • @Yunnosch 是的,它也失败了。 @尤金·什。 DO_MACRO 很有希望,我还得测试一下有没有可能
  • “带括号的字符串文字”是否意味着“(blabla)”?
  • 仅供参考,就预处理器而言,没有字符串文字连接之类的东西。特别是,C 预处理器在翻译阶段 4 中运行;字符串文字连接是翻译阶段 6 的功能。

标签: c gcc c-preprocessor pragma


【解决方案1】:

DO_PRAGMAin the GNU docs 是这样定义的

#define DO_PRAGMA(x) _Pragma (#x)

使用这个,如果你将两个单独的未字符串化的令牌放在一起,它们将变成字符串化的。要在定义中扩展宏,必须经过一层间接,所以定义为

#define DO_PRAGMA_(x) _Pragma (#x)
#define DO_PRAGMA(x) DO_PRAGMA_(x)

使用它,您可以为这样的各种 pragma 创建速记

#define POISON(name) DO_PRAGMA(GCC poison name)

POISON(puts) // becomes _Pragma("GCC poison puts")

感谢 Eugene Sh。将我指向DO_PRAGMA

【讨论】:

  • 是否可以转义更复杂的编译指示表达式,例如 DO_PRAGMA("comment(linker, \"/EXPORT:" #alias "=" #func "\")") ?我试图解决这个问题,但找不到解决方案;答案中提供的间接方法不起作用,因为链接器命令本身包含在引号中,可以在字符串内部转义,但不能在外部进行转义,即您不能简单地执行DO_PRAGMA(comment(linker, \"/EXPORT: #alias = #func \"))
  • @Marandil 为了在 c 中转义引号内的引号,转义在每一步都会以指数方式增大,因为您将 (//) 减少到 (/) 和 (/") 到 (")。所以你有“ -> /” -> ///“ -> ///////”等等。
  • 我并不完全清楚您希望在您给出的示例中使用引号做什么,但您可能不希望外部引号,因为它会被字符串化。所以也许像DO_PRAGMA(comment(linker, "/EXPORT:\" #alias \"=\" #func \""))
  • 说我想创建一个宏ALIAS(alias, func),给定两个符号(比如foobar)生成_Pragma("comment(linker, \"/EXPORT:foo=bar\")"),这相当于#pragma comment(linker, "/EXPORT:foo=bar") 与pragma 作为预处理指令。
  • 好吧,我想我找到了一个总共4层宏的解决方案。起初我没有考虑过,但我所要做的就是使用# 运算符创建两个字符串。 #define API_ALIAS_NESTED_3(part) _Pragma(#part),然后是 #define API_ALIAS_NESTED_2(part) API_ALIAS_NESTED_3(comment(linker, part))#define API_ALIAS_NESTED_1(part) API_ALIAS_NESTED_2(#part),最后是 #define API_ALIAS(alias, func) API_ALIAS_NESTED_1(/EXPORT:alias=func)。感谢您的启发!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
相关资源
最近更新 更多