这是一个说明我的问题的程序:
#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"
传递给编译器,但我失去了希望。
这与this question有关,但会增加一个级别。
答案 0 :(得分:4)
您可以定义将其参数粘贴在一起的宏,然后定义(大量)其他宏来执行评估作为表查找的类型:
#define DIV(X, Y) DIV_(X, Y)
#define DIV_(X, Y) DIV_##X##_##Y
#define DIV_0_1 0
#define DIV_1_1 1
#define DIV_2_1 2
:
#define DIV_8_2 4
:
这有点乏味,但您可以轻松编写一个小程序来生成包含上述内容的头文件,并将其作为构建过程的一部分运行。那你就需要
#define QUOTIENT DIV(NUMERATOR, DENOMINATOR)
请注意,他的那种东西只适用于无符号整数 - 如果你需要负数或浮点数,它将不起作用
答案 1 :(得分:3)
通过一些技巧,您可以在符合C99的预处理器中实现基本算法。 P99为小十进制数实现算术和逻辑。 E.g
P99_IF_GT(1,0)(true)(false)
P99_ADD(3, 7)
P99_MUL(7, 2)
P99_DIV(7, 2)
将被预处理为类似
的内容1
10
14
3
这些宏可以进一步处理,字符串化并且你喜欢它们。
P99_STRINGIFY(P99_PASTE2(XXX_, P99_ADD(3, 7)))
导致"XXX_10"
作为预处理的结果。
答案 2 :(得分:2)
您可以做的最好的事情是stringify宏的扩展,这是通过您的XSTR
和YSTR
示例完成的。虽然可以通过优化编译到4
,但所有 pre 处理器都能看到(8 / 2)
答案 3 :(得分:2)
嗯,我有点不愿意承认我知道一种方法来完成这项工作。
从另一个方向攻击它。您希望编译器看到类似的内容。
#define QUOTIENT 4
#include <stdio.h>
int main(void)
{
printf("QUOTIENT: %d\n", QUOTIENT);
return 0;
}
如果不在QUOTIENT的定义中使用文字“4”,我们如何做到这一点,因为宏处理器不会帮助我们?通过使用额外的预处理器。写一个源文件stringify.c.awk,就像这样。
/* stringify.c.awk -- Source file for stringify.c
(Put build instructions here.)
*/
#define QUOTIENT NUMERATOR/DENOMINATOR
#include <stdio.h>
int main(void)
{
printf("QUOTIENT: %d\n", QUOTIENT);
return 0;
}
在awk中编写辅助预处理器。我故意用一个非常紧凑的正则表达式。如果源文件有变化,我认为这是最有可能失败的正则表达式,我认为这通常是你想要的。 (我通常希望阻止对#define进行外观修饰。)
# stringify.awk -- calculate and substitute the value for #define QUOTIENT.
BEGIN {
NUMERATOR = 8;
DENOMINATOR = 2;
}
{
if ($0~/^#define QUOTIENT NUMERATOR\/DENOMINATOR$/) {
sub(/NUMERATOR\/DENOMINATOR/, NUMERATOR/DENOMINATOR);
}
print $0;
}
现在您可以从stringify.c.awk文件构建stringify.c。
$ awk -f stringify.awk stringify.c.awk > stringify.c
$ gcc -Wall -o stringify stringify.c
$ ./stringify
QUOTIENT: 4
makefile和慷慨的评论会带来很多痛苦。
(m4对C预处理器没有帮助的原因或多或少有所帮助。)