在我的C Makefile中,有以下几行:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -D TRUE
else
CFLAGS += -D FALSE
endif
正如您所知道的,该标志指示我是否应该打印调试语句。
在我的C代码的其他地方,我用
定义TRUE和FALSE。#define FALSE 0
#define TRUE !FALSE
然后,当我尝试编译代码时,出现以下错误:
types.h:6:0: error: "FALSE" redefined [-Werror]
#define FALSE 0
<command-line>:0:0: note: this is the location of the previous definition
如果我从C代码中删除TRUE和FALSE的定义,我的程序就会发疯。
这是怎么回事,如何解决此冲突?
谢谢。
答案 0 :(得分:4)
对于两个不兼容的事物,您不能使用相同的名称,因此您需要更改其中之一。因为您没有任何意义,所以很可能您想更改Makefile。像这样:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -DDEBUG=1
else
CFLAGS += -DDEBUG=0
endif
然后在您的C代码中可以拥有
#if DEBUG
printf( ... debugging messages ... )
#endif
答案 1 :(得分:2)
在编译器命令行上,-DXYZ
等效于-DXYZ=1
(POSIX c99
)。这意味着在命令行上使用-DFALSE
时,您同时拥有#define FALSE 1
和#define FALSE 0
,这是非良性的重定义。可以按良性方式重新定义宏(这意味着替换令牌的顺序在当前定义和新定义中都是相同的,请参见C11 §6.10.3 Macro replacement ¶1-2。)
您需要在代码中使用其他变量来决定是否进行打印:
#ifdef VERBOSE_PRINT
printf("Debugging!\n");
#endif
然后可以在命令行上使用-DVERBOSE_PRINT
启用打印,而将其保留以禁用打印。或者,您可以使用:
#if VERBOSE_PRINT
printf("Debugging!\n");
#endif
然后您的makefile可以包含:
ifeq ($(VERBOSE_PRINT), TRUE)
CFLAGS += -DVERBOSE_PRINT=TRUE
else
CFLAGS += -DVERBOSE_PRINT=FALSE
endif
这种技术不太常见。如果您没有在编译器命令行上指定值(C11 §6.10.1 Conditional inclusion ¶4),它将像您有#define VERBOSE_PRINT 0
一样工作。