Philip L
Philip L

Reputation: 359

Variables conflict between Makefile and C code

In my C Makefile I have the following lines:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -D TRUE
else
  CFLAGS += -D FALSE
endif

As you can tell by it's name, this flag indicated whether I should print debug statements or not.

In other place at my C code, I'm defining TRUE and FALSE with

#define FALSE 0
#define TRUE !FALSE

Then when I'm trying to compile my code, I get the following error:

types.h:6:0: error: "FALSE" redefined [-Werror]
#define FALSE 0
<command-line>:0:0: note: this is the location of the previous definition

If I delete the definition of TRUE and FALSE from my C code, my program get's crazy.

What's going on and how can I solve this conflict?

Thanks ahead.

Upvotes: 1

Views: 307

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126203

You can't use the same name for two different incompatible things, so you'll need to change one of them. Most likely you want to change your Makefile, since what you have makes no sense. Something like:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -DDEBUG=1
else
  CFLAGS += -DDEBUG=0
endif

Then in your C code you can have

#if DEBUG
    printf( ... debugging messages ... )
#endif

Upvotes: 4

Jonathan Leffler
Jonathan Leffler

Reputation: 753665

On the compiler command line, -DXYZ is equivalent to -DXYZ=1 (POSIX c99). This means that with -DFALSE on the command line, you've got both #define FALSE 1 and #define FALSE 0, which is a non-benign redefinition. Benign redefinition of a macro is OK (meaning that the sequence of replacement tokens is the same in both the current and new definition — see C11 §6.10.3 Macro replacement ¶1-2).

You need to use a different variable in your code to decide whether to do printing:

#ifdef VERBOSE_PRINT
    printf("Debugging!\n");
#endif

You can then use -DVERBOSE_PRINT on the command line to enable printing and leave it out to disable it. Alternatively, you can use:

#if VERBOSE_PRINT
    printf("Debugging!\n");
#endif

Then your makefile can contain:

ifeq ($(VERBOSE_PRINT), TRUE)
  CFLAGS += -DVERBOSE_PRINT=TRUE
else
  CFLAGS += -DVERBOSE_PRINT=FALSE
endif

This technique is less common. It will work as if you have #define VERBOSE_PRINT 0 if you don't specify a value on the compiler command line (C11 §6.10.1 Conditional inclusion ¶4).

Upvotes: 2

Related Questions