Can you #define values for a header in another file?

EDIT: Sorry for the confusion. Let me rephrase what I meant to ask: Given the code below, where should I put the #define DEBUG_ENABLE 1 so that I can toggle debug messages before compiling?

My project directory tree looks like this:

1
2
3
4
5
\Project1\
   |- Main.cpp
\Utilities\
   |- Logger.h
   |- Logger.cpp


Main.cpp
1
2
3
4
5
6
7
8
9
10
#include "Logger.h"

// #define DEBUG_ENABLE 1

int main() 
{
   char msg[] = "Hello";
   DEBUG("%s World!", msg);
   return 0;
}


Logger.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef LOGGER_H
#define LOGGER_H

#include <cstdio>

// #define DEBUG_ENABLE 1

#if DEBUG_ENABLE
#define DEBUG(format, ...) printf("DEBUG %s:%s %d - " format "\r\n", __FILE__, __func__, __LINE__, __VA_ARGS__);
#define DEBUG_MSG(msg) printf("DEBUG %s:%s %d - " msg "\r\n");
#else
#define DEBUG(format, ...)
#define DEBUG_MSG(msg)
#endif

#endif 


Logger.cpp
1
2
3
#include "Logger.h"

//#define DEBUG_ENABLE 1  


It seems the preprocessor only performs the macro substitution #define DEBUG_ENABLE 1 locally for the file. The #define in Logger.cpp and Main.cpp don't disable or enable the debug switch in Logger.h.

I've tried this in Visual Studio and an Eclipse-based IDE where the project properties allow you to #define symbols and give them a value -- but what's the point of this feature if the only way to enable the switch is to #define it from its header?
Last edited on
If you #define a macro to some value just before using it, there isn't much you can do elsewhere to override that value, be it in the file that include that header or in the compiler options. Now matter what you set it to, that #define is going to override the previous value.

By the way, it's standard behavior for compilers to define _DEBUG if and only if the build is for debug, and to define NDEBUG otherwise.
You have #include directive. Preprocessor includes:

Translation unit for Logger.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// begin include Logger.h
#ifndef LOGGER_H
#define LOGGER_H

#include <cstdio> // this will expand to content of <cstdio>

#define DEBUG_ENABLE 1

#if DEBUG_ENABLE
#define DEBUG(format, ...) printf("DEBUG %s:%s %d - " format "\r\n", __FILE__, __func__, __LINE__, __VA_ARGS__);
#define DEBUG_MSG(msg) printf("DEBUG %s:%s %d - " msg "\r\n");
#else
#define DEBUG(format, ...)
#define DEBUG_MSG(msg)
#endif

#endif
// end include Logger.h

#define DEBUG_ENABLE 0 

The value of DEBUG_ENABLE is tested on line 9. It was set on line 7. Changing it on line 20 or before line 1 will not make a difference.
helios wrote:
If you #define a macro to some value just before using it, there isn't much you can do elsewhere to override that value, be it in the file that include that header or in the compiler options. Now matter what you set it to, that #define is going to override the previous value.


I think I provided poor sample code to go with the question. I understand that the preprocessor runs exactly once through a source file to process the preprocessor directives.

Ah .. I just realized: in Main.cpp Line #1 and in Logger.cpp Line #1, I'd #included "logger.h" before I'd #define DEBUG_ENABLE . This means the resolution of the conditional in Logger.h Line #2 preceded the definition of DEBUG_ENABLE and goes to the #else case every time.

That would explain why Logger.h Line #1 is the only place where #define does its job: it's guaranteed to run before the condition is checked, no matter when #include "Logger.h" is processed (i.e., whether in Logger.cpp or in Main.cpp).

What I need then, is to ensure that #define DEBUG_ENABLE 1 happens before those #includes.

Last edited on
Confirmed. This version works.

Main.cpp
1
2
3
4
5
6
7
8
9
#define DEBUG_ENABLE 0
#include "Logger.h"

int main() 
{
	char msg[] = "Hello";
	DEBUG("%s World!", msg);
	return 0;
}


Logger.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef LOGGER_H
#define LOGGER_H

#include <cstdio>

//#define DEBUG_ENABLE 1

#if DEBUG_ENABLE
#define DEBUG(format, ...) printf("DEBUG %s:%s %d - " format "\r\n", __FILE__, __func__, __LINE__, __VA_ARGS__);
#define DEBUG_MSG(msg) printf("DEBUG %s:%s %d - " msg "\r\n");
#else
#define DEBUG(format, ...)
#define DEBUG_MSG(msg)
#endif

#endif 


Logger.cpp
1
2
3
#include "Logger.h"

// #define DEBUG_ENABLE 1 


I must define DEBUG_ENABLE at only one location because if we didn't and we had this situation (and assuming Logger.h did not #define DEBUG_ENABLE):

Main.cpp
1
2
3
4
5
6
7
8
9
#define DEBUG_ENABLE 1
#include "Logger.h"

int main() 
{
	char msg[] = "Hello";
	DEBUG("%s World!", msg);
	return 0;
}


Logger.cpp
1
2
#define DEBUG_ENABLE 0  
#include "Logger.h" 


whether DEBUG_ENABLE resolves to 1 or 0 depends on whether the preprocessor processed Main.cpp or Logger.cpp first (the header guard makes the definition idempotent).

So the only way to be sure that DEBUG_ENABLE is set to the value we want is to #define it in Logger.h.

I guess I need a final "ok" from a preprocessor guru and I can mark this case closed.
Last edited on
You normally want to set those kinds of configuration macros in the compiler settings for the project. You wouldn't want to set DEBUG_ENABLE to 0 on one translation unit and to 1 on another by accident.
Topic archived. No new replies allowed.