【问题标题】:Getting a macro to concat AND stringify获取一个宏来连接和字符串化
【发布时间】:2015-02-11 13:57:36
【问题描述】:

C/C++ 在预处理器宏中的连接方法是使用##。 字符串化的方法是使用#。 我正在尝试连接和字符串化。这会从 g++ (3.3.2) 生成警告

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)      // concat
#define TOKENPASTE3(x, y) TOKENPASTE(#x, #y)    // concat-stringify (warnings)
const char* s = TOKENPASTE3(Hi, There)

收到警告是不可接受的

"test_utils/test_registration.h:34:38: 警告:粘贴 ""Hi"" 和 ""那里"" 没有提供有效的预处理令牌"

虽然(使用 -E 选项)我看到它生成:

const char* s = "Hi""There";

我觉得很合适。

任何帮助将不胜感激。

【问题讨论】:

  • 您为什么使用已有十多年历史的 GCC 版本?
  • 它实际上是十年前的安全关键分支。它来自 WindRiver 653。这是我无法控制的。
  • 好吧,你已经有了两个字符串,在#x#y之后;您不需要将它们连接成单个令牌,只需使用 #x #y
  • 那个 concat 是不必要的。 "Hi" "There" 将被解释为 "HiThere" 即使不这样做。
  • 预处理器根本不允许使用连接运算符连接字符串。来自this reference:“只能粘贴构成有效令牌的令牌”。字符串文字连接由另一个 compiler phase 处理。

标签: c macros c-preprocessor string-concatenation


【解决方案1】:

预处理器已经连接了相邻的字符串文字。所以你的宏是不必要的。示例:

#define TOKENPASTE3(x, y) #x #y
const char* s = TOKENPASTE3(Hi, There);

变成"Hi" "There"。但是,如果您想坚持自己的方法,则需要使用额外的间接级别来宏扩展您的新令牌:

#define STRINGIFY(x) #x
#define TOKENPASTE(x, y) STRINGIFY(x ## y)

变成"HiThere"

【讨论】:

    猜你喜欢
    • 2023-04-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2011-07-12
    • 1970-01-01
    相关资源
    最近更新 更多