Matti Jokipii
Matti Jokipii

Reputation: 589

Control macro compilation per source file with define

Is it possible to have a header file compile differently in two different source files by using defines in the source files?

For example, if i have a single header included in two source files as in:

header.h:

#if FOO
#define BAR(x) f(x)
#else
#define BAR(x) g(x)
#endif

source1.cpp:

#define FOO 1
#include "header.h"

void a(int x) {
    BAR(x); // f(x)?
}

source2.cpp

#include "header.h"

void b(int x) {
    BAR(x); // g(x)?
}

Should this not compile so that function a performs f and function b performs g?

I'm trying to do this in XCode and Objective-C++. Both a and b perform g as if source1.cpp didn't define FOO.

Upvotes: 2

Views: 529

Answers (3)

Matti Jokipii
Matti Jokipii

Reputation: 589

The problem was that the header was after all indirectly included in the precompiled headers. XCode seems to include the precompiled headers automatically to every compilation unit, therefore only one version of the macro was available. The version precompiled was the one without the definition i.e. the #else-branch because no source files has been read at the time of the precompilation.

I will accept Peter M's answer as he came to the right conclusion about this.

The toggle method by askmish didn't help in my case, but that's the way i'll do this in the future, since that would have lead to the solution immediately.

Upvotes: 0

Peter M
Peter M

Reputation: 7493

Your macro is defined incorrectly correctly. The mistake is that it should be However I prefer to use #ifdef and not #if

#ifdef FOO
#define BAR(x) f(x)
#else
#define BAR(x) g(x)
#endif

In addition you do not have to give FOO a value, all you need to do is to #define it in source1.cpp

#define FOO
#include "header.h"

In source2.cpp I would also ensure that FOO is not defined (as a carry over from any other includes) by doing:

#ifdef FOO
#undef FOO
#endif
#include "header.h"

EDIT

I was a bit quick to say that the macro was wrong. As per this SO question What is the value of an undefined constant used in #if? (C++) the #if should work as given by the OP, as the value of FOO should decay to 0 when it is not defined.

However I think that using #ifdef provides more context as to what is actually desired.

Thus I suspect that the definition of FOO is sneaking in unexpectedly somewhere.

Upvotes: 2

askmish
askmish

Reputation: 6674

For your case, The best way to differentiate based on macros is, using the toggle method:

#ifdef FOO
#define BAR(x) f(x)
#undef FOO
#else
#define BAR(x) g(x)
#endif

source1.cpp:

#define FOO
#include "header.h"

void a(int x) {
    BAR(x); // f(x)?
}

source2.cpp

#undef FOO
#include "header.h"  
void b(int x) {
    BAR(x); // g(x)?
}

For more control try this:

#ifdef FOO
  #if FOO == 1
  #define BAR(x) f(x)
  #undef FOO
  #elif FOO == 2
  #define BAR(x) g(x)
  #undef FOO
  #endif
#endif

And write like this:

source1.cpp:

#undef FOO
#define FOO 1
#include "header.h"

void a(int x) {
    BAR(x); // f(x)?
}

source2.cpp

#undef FOO
#define FOO 2
#include "header.h"  
void b(int x) {
    BAR(x); // g(x)?
}

There are several ways you can achieve, what you asked. Hope this helps.

Upvotes: 0

Related Questions