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


假设我想 联合国字符串化 应该转换的宏参数 "text" 至 text

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

现在调用此宏将删除 "" 从它的论点

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

这与宏字符串化相反:

#define STRINGIFY(x) #x

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


7867
2018-04-18 13:43


起源

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


答案:


这是不可能的。这可能是一件好事:如果你传递一个字符串,你就会认为你可以把所有东西放进去。对它进行非字符串化会突然导致编译器实际关注该字符串的内容。


14
2018-04-18 13:44



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


我已经好几次来到这个问题但仍然无法理解。考虑这个例子:

#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)

然后就没有必要去字符串了。如果你发现自己想要通过一个未知的宏去字符串字符串 之前 编译时,无论如何你的错误轨道;)。


0
2018-06-02 12:18