Baptiste Wicht
Baptiste Wicht

Reputation: 7663

How to get a boolean indicating if a macro is defined or not?

My code is configurable with define macros. To get the value in the code, I'm doing this:

#ifdef CONFIG_X
static constexpr bool x = true;
#else
static constexpr bool x = false;
#endif

But this is quickly becoming very ugly in the code with several configuration variables...

Another solution I found is simply to cut the code in two:

#ifdef CONFIG_X
#define CONFIG_X_BOOL true
#else
#define CONFIG_X_BOOL false
#endif

static constexpr bool x = CONFIG_X_BOOL;

This is a bit better, but not really nice either.

Is there a nice way to have a boolean or a 1 or 0 if a macro is defined ?

Upvotes: 9

Views: 5565

Answers (2)

Charles Ofria
Charles Ofria

Reputation: 2006

This IS possible, but only in the limited case where you are looking for empty defines (as is often the case with compilation flags) or where you know the range of ways a flag will be defined, such as with a 0 or 1.

Here is working code:

#include <iostream>

// Define two genetic macros
#define SECOND_ARG(A,B,...) B
#define CONCAT2(A,B) A ## B

// If a macro is detected, add an arg, so the second one will be 1.
#define DETECT_EXIST_TRUE ~,1

// DETECT_EXIST merely concats a converted macro to the end of DETECT_EXIST_TRUE.
// If empty, DETECT_EXIST_TRUE converts fine.  If not 0 remains second argument.
#define DETECT_EXIST(X) DETECT_EXIST_IMPL(CONCAT2(DETECT_EXIST_TRUE,X), 0, ~)
#define DETECT_EXIST_IMPL(...) SECOND_ARG(__VA_ARGS__)

// We will create MY_DEFINE, but not MY_DEFINE2
#define MY_DEFINE

int main()
{
  // We can now use DETECT_EXIST to detect defines.
  std::cout << "MY_DEFINE = " << DETECT_EXIST(MY_DEFINE) << std::endl;
  std::cout << "MY_DEFINE2 = " << DETECT_EXIST(MY_DEFINE2) << std::endl;
}

This code will produce the output:

MY_DEFINE = 1
MY_DEFINE2 = 0

Since the first one does exist and the second doesn't.

If the macro is set to a value such as 1, you just need to have an alternate version of DETECT_EXIST_TRUE to handle it, with the macro value pasted on the end. For example:

#define DETECT_EXIST_TRUE1 ~,1

Then if you have:

#define MY_DEFINE1 1

Code like this will also work correctly in main:

std::cout << "MY_DEFINE1 = " << DETECT_EXIST(MY_DEFINE1) << std::endl;

Upvotes: 5

Malcolm McLean
Malcolm McLean

Reputation: 6404

  #ifndef CONFIG_X
  #error "Written for config x"
  #endif


    // True for config x, hack this about for other configurations
   static bool x = 1;

Now it breaks if config is not x. Generally that's better than trying to second-guess what an unnamed configuration which is not X will require.

Upvotes: 0

Related Questions