在gcc命令行中,我想定义一个字符串,例如-Dname=Mary
,然后在源代码中我要printf("%s", name);
打印Mary
。
我该怎么办?
在gcc命令行中,我想定义一个字符串,例如-Dname=Mary
,然后在源代码中我要printf("%s", name);
打印Mary
。
我该怎么办?
Answers:
两种选择。首先,将引号转义,以使外壳不会吃掉它们:
gcc -Dname=\"Mary\"
或者,如果确实需要-Dname = Mary,则可以对其进行字符串化,尽管它有点笨拙。
#include <stdio.h>
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
int main(int argc, char *argv[])
{
printf("%s", STRINGIZE_VALUE_OF(name));
}
请注意,STRINGIZE_VALUE_OF会很高兴地求值到宏的最终定义。
到目前为止,我发现的最可移植的方式是使用\"Mary\"
-它不仅适用于gcc,而且适用于任何其他C编译器。例如,如果您尝试/Dname='"Mary"'
与Microsoft编译器一起使用,它将停止并显示错误,但/Dname=\"Mary\"
可以使用。
在Ubuntu中,我使用了一个定义CFLAGS的别名,CFLAGS包含了一个定义字符串的宏,然后在Makefile中使用CFLAGS。我必须转义双引号和\字符。它看起来像这样:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
1) DEFINES=-DLOGPATH=\"./logfile\" CFLAGS = -v $(DEFINES)....
2) DEFINES=-DLOGPATH=\\\"./logfile\\\" CFLAGS = "-v $(DEFINES)...."
使用-v编译器选项对查看预处理器的工作很有用。
这是一个简单的示例:
#include <stdio.h>
#define A B+20
#define B 10
int main()
{
#ifdef __DEBUG__
printf("__DEBUG__ DEFINED\n");
printf("%d\n",A);
#else
printf("__DEBUG__ not defined\n");
printf("%d\n",B);
#endif
return 0;
}
如果我编译:
$gcc test.c
输出:
__DEBUG__ not defined
10
如果我编译:
$gcc -D __DEBUG__ test.c
输出:
__DEBUG__ defined
30
仅供参考:显然,即使在同一系统上,同一工具链的不同版本在这方面也可以发挥不同的作用……(例如,这似乎是一个绕过shell的问题,但显然不仅限于shell)。
在这里,我们使用相同的makefile和main.c来实现xc32-gcc 4.8.3与(avr-)gcc 4.7.2(以及其他几个),唯一的区别是'make CC=xc32-gcc'
,等等。
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
几年来一直在许多版本的gcc(和bash)上使用。
为了使其与xc32-gcc兼容(并根据另一条声称\“比'”更可移植的注释),必须执行以下操作:
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"
ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif
使发现时确实令人困惑:显然,带引号的-D加上//会导致#define的末尾带有注释...例如
THINGDIR=/thingDir/
-> #define /thingDir//thing.h
->#define /thingDir
(感谢这里的答案s的帮助)。
-DNAME=\"Mary\"
)用于将要以这种方式定义的令牌,以使它们看起来像其他宏。