如何对作为宏操作结果的宏进行字符串化?
这是一个说明我的问题的程序:
#include <stdio.h>
#define NUMERATOR 8
#define DENOMINATOR 2
#define QUOTIENT (NUMERATOR / DENOMINATOR)
#define ZSTR(x) XSTR(#x)
#define YSTR(x) XSTR(x)
#define XSTR(x) STR(x)
#define STR(x) #x
int main()
{
printf("QUOTIENT: %d\n", QUOTIENT);
printf("STR(QUOTIENT): %s\n", STR(QUOTIENT));
printf("XSTR(QUOTIENT): %s\n", XSTR(QUOTIENT));
printf("YSTR(QUOTIENT): %s\n", YSTR(QUOTIENT));
printf("ZSTR(QUOTIENT): %s\n", ZSTR(QUOTIENT));
return 0;
}
这是它的输出:
$ gcc -g -Wall -o stringify stringify.c && ./stringify
QUOTIENT: 4
STR(QUOTIENT): QUOTIENT
XSTR(QUOTIENT): (8 / 2)
YSTR(QUOTIENT): (8 / 2)
ZSTR(QUOTIENT): "QUOTIENT"
我希望将字符串文字 "4"
传递给编译器,但我失去了希望。 这与此问题相关,但增加了一个级别。
Here's a program that illustrates my problem:
#include <stdio.h>
#define NUMERATOR 8
#define DENOMINATOR 2
#define QUOTIENT (NUMERATOR / DENOMINATOR)
#define ZSTR(x) XSTR(#x)
#define YSTR(x) XSTR(x)
#define XSTR(x) STR(x)
#define STR(x) #x
int main()
{
printf("QUOTIENT: %d\n", QUOTIENT);
printf("STR(QUOTIENT): %s\n", STR(QUOTIENT));
printf("XSTR(QUOTIENT): %s\n", XSTR(QUOTIENT));
printf("YSTR(QUOTIENT): %s\n", YSTR(QUOTIENT));
printf("ZSTR(QUOTIENT): %s\n", ZSTR(QUOTIENT));
return 0;
}
And here's its output:
$ gcc -g -Wall -o stringify stringify.c && ./stringify
QUOTIENT: 4
STR(QUOTIENT): QUOTIENT
XSTR(QUOTIENT): (8 / 2)
YSTR(QUOTIENT): (8 / 2)
ZSTR(QUOTIENT): "QUOTIENT"
I would like to have a the string literal "4"
passed to the compiler, but I'm losing hope.
This is related to this question, but adds a level.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以定义将其参数粘贴在一起的宏,然后定义(大量)其他宏,这些宏以表查找的方式进行评估:
这有点乏味,但您可以轻松编写一个小程序来生成头文件包含上述内容并将其作为构建过程的一部分运行。那么你只需要
注意,他的这种东西只适用于无符号整数——如果你需要负数或浮点数,它就不起作用
You can define macros that paste together their arguments and then define a (large) number of other macros that do the evaluation as kind of a table lookup:
This is kind of tedious, but you can easily write a little program to generate a header file with the above stuff in it and run that as part of your build process. Then you just need
Note that his kind of thing only works for unsigned integers -- if you need negative numbers or floating point, it won't work
通过一些技巧,您可以在符合 C99 的预处理器中实现基本算术。 P99 实现小十进制数的算术和逻辑。例如,
可以将其预处理为类似的内容
。这些宏可以进一步处理、字符串化以及您喜欢的任何内容。
预处理结果为
“XXX_10”
。With some tricks you can implement basic arithmetic in a C99 conforming preprocessor. P99 implements arithmetic and logic for small decimal numbers. E.g
would be preprocessed to something like
These macros can be processed further, stringified and everthing you like.
leads to
"XXX_10"
as the result of preprocessing.你能做的最好的事情就是 stringify 宏的扩展,这是用你的
XSTR
和YSTR
示例。尽管它可能通过优化编译为4
,但所有预处理器将能够看到的是(8 / 2)
The best you can do is stringify the expansion of the macro which is done with your
XSTR
andYSTR
examples. Although it may compile to4
with optimizations all the preprocessor will be able see is(8 / 2)
好吧,我有点不愿意承认我知道一种方法来完成这项工作。
从另一个方向攻击它。你希望你的编译器看到这样的东西。
既然宏处理器无法帮助我们,那么我们如何在 QUOTIENT 的定义中不使用文字“4”的情况下做到这一点呢?通过使用额外的预处理器。编写一个源文件 stringify.c.awk,如下所示。
用 awk 编写辅助预处理器。我故意使用了非常严格的正则表达式。我认为如果源文件发生更改,它是最有可能失败的正则表达式,而且我认为这通常就是您想要的。 (我通常不希望对 #define 进行修饰性更改。)
现在您可以从 stringify.c.awk 文件构建 stringify.c。
一个 makefile 和慷慨的注释可以消除很多痛苦。
(m4 没有帮助的原因或多或少与 C 预处理器没有帮助的原因相同。)
Well, I'm a little reluctant to admit I know one way to make this work.
Attack it from the other direction. You want your compiler to see something like this.
How do we do that without using a literal "4" in the definition of QUOTIENT, since the macro processor won't help us? By using an additional preprocessor. Write a source file, stringify.c.awk, like this.
Write the secondary preprocessor in awk. I deliberately used a really tight regular expression. I think it's the most likely regex to fail if there are changes to the source file, and I think that's usually what you want. (I usually want to discourage cosmetic changes to the #define.)
Now you can build stringify.c from the stringify.c.awk file.
A makefile and generous comments takes a lot of the pain away.
(m4 won't help for more or less the same reasons the C preprocessor won't help.)