有没有办法删除 C 宏中的引号?

Posted

技术标签:

【中文标题】有没有办法删除 C 宏中的引号?【英文标题】:Is there a way to remove quotes in a C macro? 【发布时间】:2012-04-29 22:35:27 【问题描述】:

假设我想取消字符串化应该将"text" 转换为text 的宏参数。

#define UN_STRINGIFY(x) /* some macro magic here */

现在调用此宏将从其参数中删除 ""

UN_STRINGIFY("text") // results in ----> text

这将与宏字符串化相反:

#define STRINGIFY(x) #x

这可能吗,还是我在玩宏观邪恶?

【问题讨论】:

如果可能的话,你想做什么? 这是不可能的;出于好奇,预期用途是什么? 好吧,通常我只会使用 stringify,但我正在重构一些宏并且不想更改调用模式。 #define THIS_MACRO(sringParam) const char* var = stringParam; 将更改为 #define THIS_MACRO(stringParam) const char* un##stringParam = stringParam; 我只会使用正则表达式搜索和替换在源代码级别修复它们并完成它...... 另一种可能的用途是传入用于构造标识符的“字符串”,其中一些可能具有现有的 CPP 宏定义。由于您只想使用这些“字符串”来构建实际的标识符名称,因此您不希望现有的 CPP 宏对其进行操作。 #ifdef/#undef/push_macro 是实现此目的的一种方法,但在可读性方面相当嘈杂。 【参考方案1】:

我已经多次提出这个问题,但我仍然无法进入我的脑海。考虑这个例子:

#define FOO(x) x

// FOO( destringify("string x;"))   // no way

auto f = "string x;";
FOO(string x;)                      // hm whats the problem?

对我来说,显然应该可以删除引号。我的意思是 string x; 只不过是 "string x;" 没有引号。问题是:这是不可能的。我认为没有技术原因,只能推测为什么没有方法可以做到这一点。

但是,我通过记住基本上所有预处理器所做的都是文本替换来说服自己,因此,在预处理器级别上,为什么要“去文本化”某些东西,无论如何,一切都只是文本。只是反过来做。当我把上面的例子改成这样:

#define FOO(x) x
#define STR(x) STRSTR(x)
#define STRSTR(x) #x

#define STR_X string x;

auto f = STR(STR_X)
FOO(STR_X)

那么就不需要去字符串化了。而且,如果您发现自己想要通过编译时未知的宏来对字符串进行反字符串化,那么无论如何您都走错了路;)。

【讨论】:

【参考方案2】:

这是不可能的。这可能是一件好事:如果你传递一个字符串,你假设你可以把几乎所有东西都放进去。取消字符串化会突然导致编译器真正关心该字符串的内容。

【讨论】:

tbh 我不相信这个论点:“取消字符串化会突然导致编译器真正关心该字符串的内容”。如果你有#define FOO(x) x,那么x 几乎可以是任何东西,当然编译器关心x 是什么。考虑auto f = "some string"; FOO(some string),这里x 只是一个没有引号的字符串。 Afaik 编译器甚至不知道它要处理的代码是否是宏扩展的结果。 "这里的 x 只是一个没有引号的字符串。" - 不,x 是一系列预处理器标记。

以上是关于有没有办法删除 C 宏中的引号?的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中的宏中替换宏

C/C++ 宏中的逗号

宏中的波浪号 (~) 是啥意思?

如何用C中#define宏中的字符串常量替换函数名

从 SQL Server 中的所有列中删除引号

如果比较列表,Clojure的deftest宏中的断言错误