我面临一个棘手的问题。我想根据编译器命令行伪造一个 C 源文件内容。例如(使用VC):
如果我使用命令行
cl -c -E -Dfoo=rice test.c
我希望获得实际 C 内容(预处理后):
char *s = "rice";
如果我使用命令行
cl -c -E -Dfoo=ball test.c
我希望获得实际的 C 源文件内容:
char *s = "ball";
现在找到解决方案......
首先尝试:
// test.c
#define STRNAME(n) #n
char *s = STRNAME(foo);
- 没有运气。无论foo被定义为命令行,我总是得到
char *s = "foo"; // Oh no!
SECOND TRY(最接近我可以拍照,但仍然很详细):
// test.c
#define STRNAME(n) #n
char *s = foo;
这一次,我必须详细更改命令行:
cl -c -E -Dfoo=STRNAME(rice) test.c
现在我
char *s = "rice";
有没有办法帮助我摆脱这种冗长?
顺便说一句:我真的不喜欢在命令参数中引入引号(使它们成为argv[x]
的一部分,因为你无法在Windows CMD和Linux Bash上可靠且可移植地编写这样的命令行 - 我想。
答案 0 :(得分:6)
在预处理器中需要额外的间接级别才能首先扩展宏。类似的东西:
#define STRNAME1(n) #n
#define STRNAME(n) STRNAME1(n)
char *s = STRNAME(foo);
这是一种相当常见的模式,会导致您的宏被扩展,然后转换为字符串,而不是仅仅转换为字符串。
答案 1 :(得分:3)
您是否尝试将带引号的字符串传递给-D
?你应该能够通过正确转义引号来做到这一点:
-D'foo="rice"'