【问题标题】:How to make a -D value from cmd line become a string?如何使 cmd 行中的 -D 值成为字符串?
【发布时间】:2012-02-07 13:56:55
【问题描述】:

我遇到了一个棘手的问题。我想根据编译器命令行伪造一个 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!

第二次尝试(我能想象的最接近,但仍然很冗长):

// 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 上可靠且可移植地编写这样的命令行——我想。

【问题讨论】:

标签: c c-preprocessor stringification


【解决方案1】:

您需要在预处理器中增加一个额外的间接级别来首先扩展您的宏。比如:

#define STRNAME1(n) #n
#define STRNAME(n) STRNAME1(n)
char *s = STRNAME(foo);

这是一种相当常见的模式,会导致您的宏被扩展并然后转换为字符串,而不是仅仅转换为字符串。

【讨论】:

  • 有人能指出 C99 规范中的哪个语句澄清了这种行为吗?关键是 foo 什么时候变成 ball#bar 什么时候变成 "bar" 。我检查了 6.10.3.2 左右的 C99 部分,但发现很难理解。
【解决方案2】:

您是否尝试将带引号的字符串传递给-D?您应该能够通过正确转义引号来做到这一点:

-D'foo="rice"'

【讨论】:

  • 这适用于 Linux Bash,但不适用于 Windows CMD。在 CMD 上,如果是 argv[1],则其值为 -D'foo=rice',strlen(argv[1]) 为 12。
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多